57#include "llvm/ADT/APFixedPoint.h"
58#include "llvm/ADT/Sequence.h"
59#include "llvm/ADT/SmallBitVector.h"
60#include "llvm/ADT/StringExtras.h"
61#include "llvm/Support/Casting.h"
62#include "llvm/Support/Debug.h"
63#include "llvm/Support/SaveAndRestore.h"
64#include "llvm/Support/SipHash.h"
65#include "llvm/Support/TimeProfiler.h"
66#include "llvm/Support/raw_ostream.h"
72#define DEBUG_TYPE "exprconstant"
75using llvm::APFixedPoint;
79using llvm::FixedPointSemantics;
86 using SourceLocExprScopeGuard =
96 return dyn_cast_or_null<FieldDecl>(
E.getAsBaseOrMember().getPointer());
101 return dyn_cast_or_null<CXXRecordDecl>(
E.getAsBaseOrMember().getPointer());
106 return E.getAsBaseOrMember().getInt();
121 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *
E) {
129 if (
const auto *FE = dyn_cast<FullExpr>(
E))
132 if (
const auto *Cast = dyn_cast<CastExpr>(
E))
133 E = Cast->getSubExpr()->IgnoreParens();
135 if (
const auto *CE = dyn_cast<CallExpr>(
E))
136 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
143 const auto *
E =
Base.dyn_cast<
const Expr *>();
152 case ConstantExprKind::Normal:
153 case ConstantExprKind::ClassTemplateArgument:
154 case ConstantExprKind::ImmediateInvocation:
159 case ConstantExprKind::NonClassTemplateArgument:
162 llvm_unreachable(
"unknown ConstantExprKind");
167 case ConstantExprKind::Normal:
168 case ConstantExprKind::ImmediateInvocation:
171 case ConstantExprKind::ClassTemplateArgument:
172 case ConstantExprKind::NonClassTemplateArgument:
175 llvm_unreachable(
"unknown ConstantExprKind");
181 static const uint64_t AssumedSizeForUnsizedArray =
182 std::numeric_limits<uint64_t>::max() / 2;
192 bool &FirstEntryIsUnsizedArray) {
195 assert(!isBaseAnAllocSizeCall(
Base) &&
196 "Unsized arrays shouldn't appear here");
197 unsigned MostDerivedLength = 0;
200 Type = getType(
Base).getNonReferenceType();
202 for (
unsigned I = 0, N =
Path.size(); I != N; ++I) {
206 MostDerivedLength = I + 1;
209 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
210 ArraySize = CAT->getZExtSize();
212 assert(I == 0 &&
"unexpected unsized array designator");
213 FirstEntryIsUnsizedArray =
true;
214 ArraySize = AssumedSizeForUnsizedArray;
220 MostDerivedLength = I + 1;
223 Type = VT->getElementType();
224 ArraySize = VT->getNumElements();
225 MostDerivedLength = I + 1;
228 Type = FD->getType();
230 MostDerivedLength = I + 1;
238 return MostDerivedLength;
242 struct SubobjectDesignator {
246 LLVM_PREFERRED_TYPE(
bool)
247 unsigned Invalid : 1;
250 LLVM_PREFERRED_TYPE(
bool)
251 unsigned IsOnePastTheEnd : 1;
254 LLVM_PREFERRED_TYPE(
bool)
255 unsigned FirstEntryIsAnUnsizedArray : 1;
258 LLVM_PREFERRED_TYPE(
bool)
259 unsigned MostDerivedIsArrayElement : 1;
263 unsigned MostDerivedPathLength : 28;
272 uint64_t MostDerivedArraySize;
281 SubobjectDesignator() : Invalid(
true) {}
284 : Invalid(
false), IsOnePastTheEnd(
false),
285 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
286 MostDerivedPathLength(0), MostDerivedArraySize(0),
287 MostDerivedType(
T.isNull() ?
QualType() :
T.getNonReferenceType()) {}
290 : Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
291 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
292 MostDerivedPathLength(0), MostDerivedArraySize(0) {
293 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
295 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
296 llvm::append_range(Entries,
V.getLValuePath());
297 if (
V.getLValueBase()) {
298 bool IsArray =
false;
299 bool FirstIsUnsizedArray =
false;
300 MostDerivedPathLength = findMostDerivedSubobject(
301 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
302 MostDerivedType, IsArray, FirstIsUnsizedArray);
303 MostDerivedIsArrayElement = IsArray;
304 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
310 unsigned NewLength) {
314 assert(
Base &&
"cannot truncate path for null pointer");
315 assert(NewLength <= Entries.size() &&
"not a truncation");
317 if (NewLength == Entries.size())
319 Entries.resize(NewLength);
321 bool IsArray =
false;
322 bool FirstIsUnsizedArray =
false;
323 MostDerivedPathLength = findMostDerivedSubobject(
324 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
325 FirstIsUnsizedArray);
326 MostDerivedIsArrayElement = IsArray;
327 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
337 bool isMostDerivedAnUnsizedArray()
const {
338 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
339 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
344 uint64_t getMostDerivedArraySize()
const {
345 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
346 return MostDerivedArraySize;
350 bool isOnePastTheEnd()
const {
354 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
355 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
356 MostDerivedArraySize)
364 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
365 if (Invalid || isMostDerivedAnUnsizedArray())
371 bool IsArray = MostDerivedPathLength == Entries.size() &&
372 MostDerivedIsArrayElement;
373 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
374 : (uint64_t)IsOnePastTheEnd;
376 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
377 return {ArrayIndex, ArraySize - ArrayIndex};
381 bool isValidSubobject()
const {
384 return !isOnePastTheEnd();
392 assert(!Invalid &&
"invalid designator has no subobject type");
393 return MostDerivedPathLength == Entries.size()
404 MostDerivedIsArrayElement =
true;
406 MostDerivedPathLength = Entries.size();
410 void addUnsizedArrayUnchecked(
QualType ElemTy) {
413 MostDerivedType = ElemTy;
414 MostDerivedIsArrayElement =
true;
418 MostDerivedArraySize = AssumedSizeForUnsizedArray;
419 MostDerivedPathLength = Entries.size();
423 void addDeclUnchecked(
const Decl *
D,
bool Virtual =
false) {
427 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
D)) {
428 MostDerivedType = FD->getType();
429 MostDerivedIsArrayElement =
false;
430 MostDerivedArraySize = 0;
431 MostDerivedPathLength = Entries.size();
435 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
440 MostDerivedType = EltTy;
441 MostDerivedIsArrayElement =
true;
442 MostDerivedArraySize = 2;
443 MostDerivedPathLength = Entries.size();
446 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
449 MostDerivedType = EltTy;
450 MostDerivedPathLength = Entries.size();
451 MostDerivedArraySize = 0;
452 MostDerivedIsArrayElement =
false;
455 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *
E);
456 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *
E,
459 void adjustIndex(EvalInfo &Info,
const Expr *
E,
APSInt N,
const LValue &LV);
463 enum class ScopeKind {
471 CallRef() : OrigCallee(), CallIndex(0), Version() {}
472 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
473 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
475 explicit operator bool()
const {
return OrigCallee; }
501 CallStackFrame *Caller;
523 typedef std::pair<const void *, unsigned> MapKeyTy;
524 typedef std::map<MapKeyTy, APValue>
MapTy;
536 unsigned CurTempVersion = TempVersionStack.back();
538 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
540 void pushTempVersion() {
541 TempVersionStack.push_back(++CurTempVersion);
544 void popTempVersion() {
545 TempVersionStack.pop_back();
549 return {Callee, Index, ++CurTempVersion};
560 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
561 FieldDecl *LambdaThisCaptureField =
nullptr;
563 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
569 APValue *getTemporary(
const void *Key,
unsigned Version) {
570 MapKeyTy KV(Key, Version);
571 auto LB = Temporaries.lower_bound(KV);
572 if (LB != Temporaries.end() && LB->first == KV)
578 APValue *getCurrentTemporary(
const void *Key) {
579 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
580 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
581 return &std::prev(UB)->second;
586 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
587 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
588 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
589 return std::prev(UB)->first.second;
597 template<
typename KeyT>
599 ScopeKind
Scope, LValue &LV);
604 void describe(llvm::raw_ostream &OS)
const override;
606 Frame *getCaller()
const override {
return Caller; }
607 SourceRange getCallRange()
const override {
return CallRange; }
610 bool isStdFunction()
const {
611 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
612 if (DC->isStdNamespace())
619 bool CanEvalMSConstexpr =
false;
627 class ThisOverrideRAII {
629 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
630 : Frame(Frame), OldThis(Frame.This) {
632 Frame.This = NewThis;
634 ~ThisOverrideRAII() {
635 Frame.This = OldThis;
638 CallStackFrame &Frame;
639 const LValue *OldThis;
644 class ExprTimeTraceScope {
646 ExprTimeTraceScope(
const Expr *
E,
const ASTContext &Ctx, StringRef Name)
647 : TimeScope(Name, [
E, &Ctx] {
652 llvm::TimeTraceScope TimeScope;
657 struct MSConstexprContextRAII {
658 CallStackFrame &Frame;
660 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
661 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
662 Frame.CanEvalMSConstexpr =
Value;
665 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
678 llvm::PointerIntPair<APValue*, 2, ScopeKind>
Value;
689 bool isDestroyedAtEndOf(ScopeKind K)
const {
690 return (
int)
Value.getInt() >= (
int)K;
692 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
693 if (RunDestructors) {
696 Loc = VD->getLocation();
705 bool hasSideEffect() {
706 return T.isDestructedType();
711 struct ObjectUnderConstruction {
714 friend bool operator==(
const ObjectUnderConstruction &LHS,
715 const ObjectUnderConstruction &RHS) {
716 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
718 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
719 return llvm::hash_combine(Obj.Base, Obj.Path);
722 enum class ConstructionPhase {
733template<>
struct DenseMapInfo<ObjectUnderConstruction> {
734 using Base = DenseMapInfo<APValue::LValueBase>;
736 return {Base::getEmptyKey(), {}}; }
738 return {Base::getTombstoneKey(), {}};
743 static bool isEqual(
const ObjectUnderConstruction &LHS,
744 const ObjectUnderConstruction &RHS) {
758 const Expr *AllocExpr =
nullptr;
769 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
770 return NE->isArray() ? ArrayNew :
New;
771 assert(isa<CallExpr>(AllocExpr));
776 struct DynAllocOrder {
804 CallStackFrame *CurrentCall;
807 unsigned CallStackDepth;
810 unsigned NextCallIndex;
819 bool EnableNewConstInterp;
823 CallStackFrame BottomFrame;
833 enum class EvaluatingDeclKind {
840 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
852 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
853 ObjectsUnderConstruction;
858 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
861 unsigned NumHeapAllocs = 0;
863 struct EvaluatingConstructorRAII {
865 ObjectUnderConstruction
Object;
867 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
871 EI.ObjectsUnderConstruction
872 .insert({
Object, HasBases ? ConstructionPhase::Bases
873 : ConstructionPhase::AfterBases})
876 void finishedConstructingBases() {
877 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterBases;
879 void finishedConstructingFields() {
880 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterFields;
882 ~EvaluatingConstructorRAII() {
883 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
887 struct EvaluatingDestructorRAII {
889 ObjectUnderConstruction
Object;
891 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
893 DidInsert = EI.ObjectsUnderConstruction
894 .insert({
Object, ConstructionPhase::Destroying})
897 void startedDestroyingBases() {
898 EI.ObjectsUnderConstruction[
Object] =
899 ConstructionPhase::DestroyingBases;
901 ~EvaluatingDestructorRAII() {
903 EI.ObjectsUnderConstruction.erase(Object);
910 return ObjectsUnderConstruction.lookup({
Base,
Path});
915 unsigned SpeculativeEvaluationDepth = 0;
923 bool HasActiveDiagnostic;
927 bool HasFoldFailureDiagnostic;
932 bool CheckingPotentialConstantExpression =
false;
940 bool CheckingForUndefinedBehavior =
false;
942 enum EvaluationMode {
945 EM_ConstantExpression,
952 EM_ConstantExpressionUnevaluated,
960 EM_IgnoreSideEffects,
965 bool checkingPotentialConstantExpression()
const override {
966 return CheckingPotentialConstantExpression;
972 bool checkingForUndefinedBehavior()
const override {
973 return CheckingForUndefinedBehavior;
977 : Ctx(const_cast<
ASTContext &>(
C)), EvalStatus(S), CurrentCall(nullptr),
978 CallStackDepth(0), NextCallIndex(1),
979 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
980 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
984 EvaluatingDecl((const
ValueDecl *)nullptr),
985 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
986 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
992 ASTContext &getASTContext()
const override {
return Ctx; }
995 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
996 EvaluatingDecl =
Base;
997 IsEvaluatingDecl = EDK;
998 EvaluatingDeclValue = &
Value;
1004 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
1006 if (NextCallIndex == 0) {
1008 FFDiag(
Loc, diag::note_constexpr_call_limit_exceeded);
1011 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
1013 FFDiag(
Loc, diag::note_constexpr_depth_limit_exceeded)
1014 << getLangOpts().ConstexprCallDepth;
1019 uint64_t ElemCount,
bool Diag) {
1025 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
1027 FFDiag(
Loc, diag::note_constexpr_new_too_large) << ElemCount;
1037 if (ElemCount > Limit) {
1039 FFDiag(
Loc, diag::note_constexpr_new_exceeds_limits)
1040 << ElemCount << Limit;
1046 std::pair<CallStackFrame *, unsigned>
1047 getCallFrameAndDepth(
unsigned CallIndex) {
1048 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1051 unsigned Depth = CallStackDepth;
1052 CallStackFrame *Frame = CurrentCall;
1053 while (Frame->Index > CallIndex) {
1054 Frame = Frame->Caller;
1057 if (Frame->Index == CallIndex)
1058 return {Frame, Depth};
1059 return {
nullptr, 0};
1062 bool nextStep(
const Stmt *S) {
1064 FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1074 std::optional<DynAlloc *> Result;
1075 auto It = HeapAllocs.find(DA);
1076 if (It != HeapAllocs.end())
1077 Result = &It->second;
1083 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1084 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1089 struct StdAllocatorCaller {
1090 unsigned FrameIndex;
1093 explicit operator bool()
const {
return FrameIndex != 0; };
1096 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1097 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1099 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1103 if (!FnII || !FnII->
isStr(FnName))
1107 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1113 if (CTSD->isInStdNamespace() && ClassII &&
1114 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1116 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1122 void performLifetimeExtension() {
1124 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1125 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1132 bool discardCleanups() {
1133 for (Cleanup &
C : CleanupStack) {
1134 if (
C.hasSideEffect() && !noteSideEffect()) {
1135 CleanupStack.clear();
1139 CleanupStack.clear();
1144 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1145 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1147 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1148 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1150 void setFoldFailureDiagnostic(
bool Flag)
override {
1151 HasFoldFailureDiagnostic = Flag;
1162 bool hasPriorDiagnostic()
override {
1163 if (!EvalStatus.
Diag->empty()) {
1165 case EM_ConstantFold:
1166 case EM_IgnoreSideEffects:
1167 if (!HasFoldFailureDiagnostic)
1171 case EM_ConstantExpression:
1172 case EM_ConstantExpressionUnevaluated:
1173 setActiveDiagnostic(
false);
1180 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1185 bool keepEvaluatingAfterSideEffect()
const override {
1187 case EM_IgnoreSideEffects:
1190 case EM_ConstantExpression:
1191 case EM_ConstantExpressionUnevaluated:
1192 case EM_ConstantFold:
1195 return checkingPotentialConstantExpression() ||
1196 checkingForUndefinedBehavior();
1198 llvm_unreachable(
"Missed EvalMode case");
1203 bool noteSideEffect()
override {
1205 return keepEvaluatingAfterSideEffect();
1209 bool keepEvaluatingAfterUndefinedBehavior() {
1211 case EM_IgnoreSideEffects:
1212 case EM_ConstantFold:
1215 case EM_ConstantExpression:
1216 case EM_ConstantExpressionUnevaluated:
1217 return checkingForUndefinedBehavior();
1219 llvm_unreachable(
"Missed EvalMode case");
1225 bool noteUndefinedBehavior()
override {
1227 return keepEvaluatingAfterUndefinedBehavior();
1232 bool keepEvaluatingAfterFailure()
const override {
1237 case EM_ConstantExpression:
1238 case EM_ConstantExpressionUnevaluated:
1239 case EM_ConstantFold:
1240 case EM_IgnoreSideEffects:
1241 return checkingPotentialConstantExpression() ||
1242 checkingForUndefinedBehavior();
1244 llvm_unreachable(
"Missed EvalMode case");
1257 [[nodiscard]]
bool noteFailure() {
1265 bool KeepGoing = keepEvaluatingAfterFailure();
1270 class ArrayInitLoopIndex {
1275 ArrayInitLoopIndex(EvalInfo &Info)
1276 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1277 Info.ArrayInitIndex = 0;
1279 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1281 operator uint64_t&() {
return Info.ArrayInitIndex; }
1286 struct FoldConstant {
1289 bool HadNoPriorDiags;
1290 EvalInfo::EvaluationMode OldMode;
1292 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1295 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1296 Info.EvalStatus.
Diag->empty() &&
1297 !Info.EvalStatus.HasSideEffects),
1298 OldMode(Info.EvalMode) {
1300 Info.EvalMode = EvalInfo::EM_ConstantFold;
1302 void keepDiagnostics() { Enabled =
false; }
1304 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1305 !Info.EvalStatus.HasSideEffects)
1306 Info.EvalStatus.Diag->clear();
1307 Info.EvalMode = OldMode;
1313 struct IgnoreSideEffectsRAII {
1315 EvalInfo::EvaluationMode OldMode;
1316 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1317 : Info(Info), OldMode(Info.EvalMode) {
1318 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1321 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1326 class SpeculativeEvaluationRAII {
1327 EvalInfo *Info =
nullptr;
1329 unsigned OldSpeculativeEvaluationDepth = 0;
1331 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1333 OldStatus =
Other.OldStatus;
1334 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1335 Other.Info =
nullptr;
1338 void maybeRestoreState() {
1342 Info->EvalStatus = OldStatus;
1343 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1347 SpeculativeEvaluationRAII() =
default;
1349 SpeculativeEvaluationRAII(
1351 : Info(&Info), OldStatus(Info.EvalStatus),
1352 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1353 Info.EvalStatus.Diag = NewDiag;
1354 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1357 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1358 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1359 moveFromAndCancel(std::move(
Other));
1362 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1363 maybeRestoreState();
1364 moveFromAndCancel(std::move(
Other));
1368 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1373 template<ScopeKind Kind>
1376 unsigned OldStackSize;
1378 ScopeRAII(EvalInfo &Info)
1379 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1382 Info.CurrentCall->pushTempVersion();
1384 bool destroy(
bool RunDestructors =
true) {
1385 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1386 OldStackSize = std::numeric_limits<unsigned>::max();
1390 if (OldStackSize != std::numeric_limits<unsigned>::max())
1394 Info.CurrentCall->popTempVersion();
1397 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1398 unsigned OldStackSize) {
1399 assert(OldStackSize <= Info.CleanupStack.size() &&
1400 "running cleanups out of order?");
1405 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1406 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1407 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1415 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1416 if (Kind != ScopeKind::Block)
1418 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1419 return C.isDestroyedAtEndOf(Kind);
1421 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1425 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1426 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1427 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1430bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *
E,
1434 if (isOnePastTheEnd()) {
1435 Info.CCEDiag(
E, diag::note_constexpr_past_end_subobject)
1446void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1448 Info.CCEDiag(
E, diag::note_constexpr_unsized_array_indexed);
1453void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1458 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1459 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1461 <<
static_cast<unsigned>(getMostDerivedArraySize());
1463 Info.CCEDiag(
E, diag::note_constexpr_array_index)
1468CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1473 Index(Info.NextCallIndex++) {
1474 Info.CurrentCall =
this;
1475 ++Info.CallStackDepth;
1478CallStackFrame::~CallStackFrame() {
1479 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1480 --Info.CallStackDepth;
1481 Info.CurrentCall = Caller;
1506 llvm_unreachable(
"unknown access kind");
1543 llvm_unreachable(
"unknown access kind");
1547 struct ComplexValue {
1555 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1557 void makeComplexFloat() { IsInt =
false; }
1558 bool isComplexFloat()
const {
return !IsInt; }
1559 APFloat &getComplexFloatReal() {
return FloatReal; }
1560 APFloat &getComplexFloatImag() {
return FloatImag; }
1562 void makeComplexInt() { IsInt =
true; }
1563 bool isComplexInt()
const {
return IsInt; }
1564 APSInt &getComplexIntReal() {
return IntReal; }
1565 APSInt &getComplexIntImag() {
return IntImag; }
1567 void moveInto(
APValue &v)
const {
1568 if (isComplexFloat())
1569 v =
APValue(FloatReal, FloatImag);
1571 v =
APValue(IntReal, IntImag);
1573 void setFrom(
const APValue &v) {
1592 bool InvalidBase : 1;
1594 bool AllowConstexprUnknown =
false;
1597 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1598 CharUnits &getLValueOffset() {
return Offset; }
1599 const CharUnits &getLValueOffset()
const {
return Offset; }
1600 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1601 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1602 bool isNullPointer()
const {
return IsNullPtr;}
1604 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1605 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1611 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1615 if (AllowConstexprUnknown)
1616 V.setConstexprUnknown();
1619 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1620 Base =
V.getLValueBase();
1621 Offset =
V.getLValueOffset();
1622 InvalidBase =
false;
1624 IsNullPtr =
V.isNullPointer();
1625 AllowConstexprUnknown =
V.allowConstexprUnknown();
1632 const auto *
E = B.
get<
const Expr *>();
1633 assert((isa<MemberExpr>(
E) || tryUnwrapAllocSizeCall(
E)) &&
1634 "Unexpected type of invalid base");
1640 InvalidBase = BInvalid;
1641 Designator = SubobjectDesignator(getType(B));
1643 AllowConstexprUnknown =
false;
1650 InvalidBase =
false;
1653 AllowConstexprUnknown =
false;
1662 moveInto(Printable);
1669 template <
typename GenDiagType>
1670 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1682 bool checkNullPointer(EvalInfo &Info,
const Expr *
E,
1684 return checkNullPointerDiagnosingWith([&Info,
E, CSK] {
1685 Info.CCEDiag(
E, diag::note_constexpr_null_subobject) << CSK;
1689 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *
E,
1691 return checkNullPointerDiagnosingWith([&Info,
E, AK] {
1692 if (AK == AccessKinds::AK_Dereference)
1693 Info.FFDiag(
E, diag::note_constexpr_dereferencing_null);
1695 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
1706 void addDecl(EvalInfo &Info,
const Expr *
E,
1711 void addUnsizedArray(EvalInfo &Info,
const Expr *
E,
QualType ElemTy) {
1713 Info.CCEDiag(
E, diag::note_constexpr_unsupported_unsized_array);
1718 assert(getType(
Base).getNonReferenceType()->isPointerType() ||
1719 getType(
Base).getNonReferenceType()->isArrayType());
1720 Designator.FirstEntryIsAnUnsizedArray =
true;
1728 void addComplex(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
bool Imag) {
1732 void addVectorElement(EvalInfo &Info,
const Expr *
E,
QualType EltTy,
1733 uint64_t Size, uint64_t Idx) {
1735 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1737 void clearIsNullPointer() {
1740 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *
E,
1750 uint64_t Offset64 = Offset.getQuantity();
1752 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1757 clearIsNullPointer();
1762 clearIsNullPointer();
1769 : DeclAndIsDerivedMember(
Decl,
false) {}
1774 return DeclAndIsDerivedMember.getPointer();
1777 bool isDerivedMember()
const {
1778 return DeclAndIsDerivedMember.getInt();
1782 return cast<CXXRecordDecl>(
1783 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1790 assert(
V.isMemberPointer());
1791 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1792 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1794 llvm::append_range(
Path,
V.getMemberPointerPath());
1800 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1808 assert(!
Path.empty());
1810 if (
Path.size() >= 2)
1814 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1830 if (!isDerivedMember()) {
1831 Path.push_back(Derived);
1834 if (!castBack(Derived))
1837 DeclAndIsDerivedMember.setInt(
false);
1845 DeclAndIsDerivedMember.setInt(
true);
1846 if (isDerivedMember()) {
1850 return castBack(
Base);
1855 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1856 if (!LHS.getDecl() || !RHS.getDecl())
1857 return !LHS.getDecl() && !RHS.getDecl();
1858 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1860 return LHS.Path == RHS.Path;
1864void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *
E,
APSInt N,
1868 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1869 if (isMostDerivedAnUnsizedArray()) {
1870 diagnoseUnsizedArrayPointerArithmetic(Info,
E);
1875 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1883 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1885 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1888 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1889 if (!Info.checkingPotentialConstantExpression() ||
1890 !LV.AllowConstexprUnknown) {
1893 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1894 (llvm::APInt &)N += ArrayIndex;
1895 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1896 diagnosePointerArithmetic(Info,
E, N);
1902 ArrayIndex += TruncatedN;
1903 assert(ArrayIndex <= ArraySize &&
1904 "bounds check succeeded for out-of-bounds index");
1907 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1909 IsOnePastTheEnd = (ArrayIndex != 0);
1915 bool AllowNonLiteralTypes =
false);
1917 bool InvalidBaseOK =
false);
1919 bool InvalidBaseOK =
false);
1933 std::string *StringResult =
nullptr);
1950 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1951 Int = Int.extend(Int.getBitWidth() + 1);
1952 Int.setIsSigned(
true);
1957template<
typename KeyT>
1959 ScopeKind
Scope, LValue &LV) {
1960 unsigned Version = getTempVersion();
1969 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1975 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1980 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1981 unsigned Version =
Base.getVersion();
1982 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1983 assert(Result.isAbsent() &&
"local created multiple times");
1989 if (Index <= Info.SpeculativeEvaluationDepth) {
1990 if (
T.isDestructedType())
1991 Info.noteSideEffect();
1993 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
2000 FFDiag(
E, diag::note_constexpr_heap_alloc_limit_exceeded);
2006 auto Result = HeapAllocs.emplace(std::piecewise_construct,
2007 std::forward_as_tuple(DA), std::tuple<>());
2008 assert(Result.second &&
"reused a heap alloc index?");
2009 Result.first->second.AllocExpr =
E;
2010 return &Result.first->second.Value;
2014void CallStackFrame::describe(raw_ostream &Out)
const {
2015 unsigned ArgIndex = 0;
2017 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
2018 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
2021 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2024 if (
This && IsMemberCall) {
2025 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
2026 const Expr *
Object = MCE->getImplicitObjectArgument();
2027 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
2029 if (
Object->getType()->isPointerType())
2033 }
else if (
const auto *OCE =
2034 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
2035 OCE->getArg(0)->printPretty(Out,
nullptr,
2036 Info.Ctx.getPrintingPolicy(),
2041 This->moveInto(Val);
2044 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2047 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2049 IsMemberCall =
false;
2055 E =
Callee->param_end(); I !=
E; ++I, ++ArgIndex) {
2056 if (ArgIndex > (
unsigned)IsMemberCall)
2060 APValue *
V = Info.getParamSlot(Arguments, Param);
2062 V->printPretty(Out, Info.Ctx, Param->
getType());
2066 if (ArgIndex == 0 && IsMemberCall)
2067 Out <<
"->" << *
Callee <<
'(';
2081 return Info.noteSideEffect();
2087 unsigned Builtin =
E->getBuiltinCallee();
2088 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2089 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2090 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
2091 Builtin == Builtin::BI__builtin_function_start);
2095 const auto *BaseExpr =
2096 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.dyn_cast<
const Expr *>());
2111 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
2112 return VD->hasGlobalStorage();
2113 if (isa<TemplateParamObjectDecl>(
D))
2118 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(
D);
2128 case Expr::CompoundLiteralExprClass: {
2132 case Expr::MaterializeTemporaryExprClass:
2135 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
2137 case Expr::StringLiteralClass:
2138 case Expr::PredefinedExprClass:
2139 case Expr::ObjCStringLiteralClass:
2140 case Expr::ObjCEncodeExprClass:
2142 case Expr::ObjCBoxedExprClass:
2143 return cast<ObjCBoxedExpr>(
E)->isExpressibleAsConstantInitializer();
2144 case Expr::CallExprClass:
2147 case Expr::AddrLabelExprClass:
2151 case Expr::BlockExprClass:
2152 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
2155 case Expr::SourceLocExprClass:
2157 case Expr::ImplicitValueInitExprClass:
2169 return LVal.Base.dyn_cast<
const ValueDecl*>();
2182 const auto *BaseExpr = LVal.Base.dyn_cast<
const Expr *>();
2187 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2188 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2196 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2197 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2198 Lit = PE->getFunctionName();
2203 AsString.
Bytes = Lit->getBytes();
2204 AsString.
CharWidth = Lit->getCharByteWidth();
2224 const LValue &RHS) {
2233 CharUnits Offset = RHS.Offset - LHS.Offset;
2234 if (Offset.isNegative()) {
2235 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2237 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2239 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2241 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2244 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2245 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2246 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2247 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2252 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2253 if (Shorter.size() + NullByte >= Longer.size())
2255 if (Longer[Shorter.size() + NullByte])
2261 return Shorter == Longer.take_front(Shorter.size());
2271 if (isa_and_nonnull<VarDecl>(
Decl)) {
2281 if (!A.getLValueBase())
2282 return !B.getLValueBase();
2283 if (!B.getLValueBase())
2286 if (A.getLValueBase().getOpaqueValue() !=
2287 B.getLValueBase().getOpaqueValue())
2290 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2291 A.getLValueVersion() == B.getLValueVersion();
2295 assert(
Base &&
"no location for a null lvalue");
2301 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2303 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2304 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2305 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2306 Idx < F->Callee->getNumParams()) {
2307 VD = F->Callee->getParamDecl(Idx);
2314 Info.Note(VD->
getLocation(), diag::note_declared_at);
2316 Info.Note(
E->
getExprLoc(), diag::note_constexpr_temporary_here);
2319 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2320 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2321 diag::note_constexpr_dynamic_alloc_here);
2354 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2362 if (isTemplateArgument(Kind)) {
2363 int InvalidBaseKind = -1;
2366 InvalidBaseKind = 0;
2367 else if (isa_and_nonnull<StringLiteral>(BaseE))
2368 InvalidBaseKind = 1;
2369 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2370 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2371 InvalidBaseKind = 2;
2372 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2373 InvalidBaseKind = 3;
2374 Ident = PE->getIdentKindName();
2377 if (InvalidBaseKind != -1) {
2378 Info.FFDiag(
Loc, diag::note_constexpr_invalid_template_arg)
2379 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2385 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2386 FD && FD->isImmediateFunction()) {
2387 Info.FFDiag(
Loc, diag::note_consteval_address_accessible)
2389 Info.Note(FD->getLocation(), diag::note_declared_at);
2397 if (Info.getLangOpts().CPlusPlus11) {
2398 Info.FFDiag(
Loc, diag::note_constexpr_non_global, 1)
2399 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2401 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2402 if (VarD && VarD->isConstexpr()) {
2408 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2420 assert((Info.checkingPotentialConstantExpression() ||
2421 LVal.getLValueCallIndex() == 0) &&
2422 "have call index for global lvalue");
2424 if (LVal.allowConstexprUnknown()) {
2426 Info.FFDiag(
Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2435 Info.FFDiag(
Loc, diag::note_constexpr_dynamic_alloc)
2436 << IsReferenceType << !
Designator.Entries.empty();
2442 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2444 if (Var->getTLSKind())
2450 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2456 if (Info.getASTContext().getLangOpts().CUDA &&
2457 Info.getASTContext().getLangOpts().CUDAIsDevice &&
2458 Info.getASTContext().CUDAConstantEvalCtx.NoWrongSidedVars) {
2459 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2460 !Var->hasAttr<CUDAConstantAttr>() &&
2461 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2462 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2463 Var->hasAttr<HIPManagedAttr>())
2467 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2478 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2479 FD->hasAttr<DLLImportAttr>())
2483 }
else if (
const auto *MTE =
2484 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2485 if (CheckedTemps.insert(MTE).second) {
2488 Info.FFDiag(MTE->getExprLoc(),
2489 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2494 APValue *
V = MTE->getOrCreateValue(
false);
2495 assert(
V &&
"evasluation result refers to uninitialised temporary");
2497 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2498 nullptr, CheckedTemps))
2505 if (!IsReferenceType)
2517 Info.FFDiag(
Loc, diag::note_constexpr_past_end, 1)
2518 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2533 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2536 if (FD->isImmediateFunction()) {
2537 Info.FFDiag(
Loc, diag::note_consteval_address_accessible) << 0;
2538 Info.Note(FD->getLocation(), diag::note_declared_at);
2541 return isForManglingOnly(Kind) || FD->isVirtual() ||
2542 !FD->hasAttr<DLLImportAttr>();
2548 const LValue *
This =
nullptr) {
2550 if (Info.getLangOpts().CPlusPlus23)
2569 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2573 if (Info.getLangOpts().CPlusPlus11)
2574 Info.FFDiag(
E, diag::note_constexpr_nonliteral)
2577 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
2588 if (SubobjectDecl) {
2589 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2590 << 1 << SubobjectDecl;
2592 diag::note_constexpr_subobject_declared_here);
2594 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2603 Type = AT->getValueType();
2608 if (
Value.isArray()) {
2610 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2612 Value.getArrayInitializedElt(I), Kind,
2613 SubobjectDecl, CheckedTemps))
2616 if (!
Value.hasArrayFiller())
2619 Value.getArrayFiller(), Kind, SubobjectDecl,
2622 if (
Value.isUnion() &&
Value.getUnionField()) {
2625 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2627 if (
Value.isStruct()) {
2629 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2630 unsigned BaseIndex = 0;
2632 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2635 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2636 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2646 for (
const auto *I : RD->fields()) {
2647 if (I->isUnnamedBitField())
2651 Value.getStructField(I->getFieldIndex()), Kind,
2657 if (
Value.isLValue() &&
2658 CERK == CheckEvaluationResultKind::ConstantExpression) {
2660 LVal.setFrom(Info.Ctx,
Value);
2665 if (
Value.isMemberPointer() &&
2666 CERK == CheckEvaluationResultKind::ConstantExpression)
2686 nullptr, CheckedTemps);
2695 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2696 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2702 if (!Info.HeapAllocs.empty()) {
2706 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2707 diag::note_constexpr_memory_leak)
2708 <<
unsigned(Info.HeapAllocs.size() - 1);
2716 if (!
Value.getLValueBase()) {
2718 Result = !
Value.getLValueOffset().isZero();
2736 Result = Val.
getInt().getBoolValue();
2768 llvm_unreachable(
"unknown APValue kind");
2774 assert(
E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2784 Info.CCEDiag(
E, diag::note_constexpr_overflow)
2785 << SrcValue << DestType;
2786 return Info.noteUndefinedBehavior();
2792 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2796 Result =
APSInt(DestWidth, !DestSigned);
2798 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2799 & APFloat::opInvalidOp)
2810 llvm::RoundingMode RM =
2812 if (RM == llvm::RoundingMode::Dynamic)
2813 RM = llvm::RoundingMode::NearestTiesToEven;
2819 APFloat::opStatus St) {
2822 if (Info.InConstantContext)
2826 if ((St & APFloat::opInexact) &&
2830 Info.FFDiag(
E, diag::note_constexpr_dynamic_rounding);
2834 if ((St != APFloat::opOK) &&
2837 FPO.getAllowFEnvAccess())) {
2838 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
2842 if ((St & APFloat::opStatus::opInvalidOp) &&
2861 assert((isa<CastExpr>(
E) || isa<CompoundAssignOperator>(
E) ||
2862 isa<ConvertVectorExpr>(
E)) &&
2863 "HandleFloatToFloatCast has been checked with only CastExpr, "
2864 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2865 "the new expression or address the root cause of this usage.");
2867 APFloat::opStatus St;
2868 APFloat
Value = Result;
2870 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2877 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2883 Result =
Value.getBoolValue();
2890 QualType DestType, APFloat &Result) {
2891 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2893 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2899 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2901 if (!
Value.isInt()) {
2905 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2911 unsigned OldBitWidth = Int.getBitWidth();
2913 if (NewBitWidth < OldBitWidth)
2914 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2921template<
typename Operation>
2924 unsigned BitWidth, Operation Op,
2926 if (LHS.isUnsigned()) {
2927 Result = Op(LHS, RHS);
2931 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2932 Result =
Value.trunc(LHS.getBitWidth());
2933 if (Result.extend(BitWidth) !=
Value) {
2934 if (Info.checkingForUndefinedBehavior())
2936 diag::warn_integer_constant_overflow)
2937 <<
toString(Result, 10, Result.isSigned(),
false,
2949 bool HandleOverflowResult =
true;
2956 std::multiplies<APSInt>(), Result);
2959 std::plus<APSInt>(), Result);
2962 std::minus<APSInt>(), Result);
2963 case BO_And: Result = LHS & RHS;
return true;
2964 case BO_Xor: Result = LHS ^ RHS;
return true;
2965 case BO_Or: Result = LHS | RHS;
return true;
2969 Info.FFDiag(
E, diag::note_expr_divide_by_zero)
2975 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2976 LHS.isMinSignedValue())
2978 Info,
E, -LHS.extend(LHS.getBitWidth() + 1),
E->
getType());
2979 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2980 return HandleOverflowResult;
2982 if (Info.getLangOpts().OpenCL)
2984 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2985 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2987 else if (RHS.isSigned() && RHS.isNegative()) {
2990 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
2991 if (!Info.noteUndefinedBehavior())
2999 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3001 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
3002 << RHS <<
E->
getType() << LHS.getBitWidth();
3003 if (!Info.noteUndefinedBehavior())
3005 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
3010 if (LHS.isNegative()) {
3011 Info.CCEDiag(
E, diag::note_constexpr_lshift_of_negative) << LHS;
3012 if (!Info.noteUndefinedBehavior())
3014 }
else if (LHS.countl_zero() < SA) {
3015 Info.CCEDiag(
E, diag::note_constexpr_lshift_discards);
3016 if (!Info.noteUndefinedBehavior())
3024 if (Info.getLangOpts().OpenCL)
3026 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
3027 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
3029 else if (RHS.isSigned() && RHS.isNegative()) {
3032 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHS;
3033 if (!Info.noteUndefinedBehavior())
3041 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
3043 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
3044 << RHS <<
E->
getType() << LHS.getBitWidth();
3045 if (!Info.noteUndefinedBehavior())
3053 case BO_LT: Result = LHS < RHS;
return true;
3054 case BO_GT: Result = LHS > RHS;
return true;
3055 case BO_LE: Result = LHS <= RHS;
return true;
3056 case BO_GE: Result = LHS >= RHS;
return true;
3057 case BO_EQ: Result = LHS == RHS;
return true;
3058 case BO_NE: Result = LHS != RHS;
return true;
3060 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
3067 const APFloat &RHS) {
3069 APFloat::opStatus St;
3075 St = LHS.multiply(RHS, RM);
3078 St = LHS.add(RHS, RM);
3081 St = LHS.subtract(RHS, RM);
3087 Info.CCEDiag(
E, diag::note_expr_divide_by_zero);
3088 St = LHS.divide(RHS, RM);
3097 Info.CCEDiag(
E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
3098 return Info.noteUndefinedBehavior();
3106 const APInt &RHSValue, APInt &Result) {
3107 bool LHS = (LHSValue != 0);
3108 bool RHS = (RHSValue != 0);
3110 if (Opcode == BO_LAnd)
3111 Result = LHS && RHS;
3113 Result = LHS || RHS;
3118 const APFloat &RHSValue, APInt &Result) {
3119 bool LHS = !LHSValue.isZero();
3120 bool RHS = !RHSValue.isZero();
3122 if (Opcode == BO_LAnd)
3123 Result = LHS && RHS;
3125 Result = LHS || RHS;
3131 const APValue &RHSValue, APInt &Result) {
3135 RHSValue.
getInt(), Result);
3141template <
typename APTy>
3144 const APTy &RHSValue, APInt &Result) {
3147 llvm_unreachable(
"unsupported binary operator");
3149 Result = (LHSValue == RHSValue);
3152 Result = (LHSValue != RHSValue);
3155 Result = (LHSValue < RHSValue);
3158 Result = (LHSValue > RHSValue);
3161 Result = (LHSValue <= RHSValue);
3164 Result = (LHSValue >= RHSValue);
3178 const APValue &RHSValue, APInt &Result) {
3182 RHSValue.
getInt(), Result);
3193 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3194 "Operation not supported on vector types");
3198 QualType EltTy = VT->getElementType();
3205 "A vector result that isn't a vector OR uncalculated LValue");
3211 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3215 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3220 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3230 RHSElt.
getInt(), EltResult);
3236 ResultElements.emplace_back(EltResult);
3241 "Mismatched LHS/RHS/Result Type");
3242 APFloat LHSFloat = LHSElt.
getFloat();
3250 ResultElements.emplace_back(LHSFloat);
3254 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3262 unsigned TruncatedElements) {
3263 SubobjectDesignator &
D = Result.Designator;
3266 if (TruncatedElements ==
D.Entries.size())
3268 assert(TruncatedElements >=
D.MostDerivedPathLength &&
3269 "not casting to a derived class");
3275 for (
unsigned I = TruncatedElements, N =
D.Entries.size(); I != N; ++I) {
3279 if (isVirtualBaseClass(
D.Entries[I]))
3285 D.Entries.resize(TruncatedElements);
3295 RL = &Info.Ctx.getASTRecordLayout(Derived);
3298 Obj.addDecl(Info,
E,
Base,
false);
3299 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3308 if (!
Base->isVirtual())
3311 SubobjectDesignator &
D = Obj.Designator;
3320 DerivedDecl =
D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
3326 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3327 Obj.addDecl(Info,
E, BaseDecl,
true);
3335 PathE =
E->path_end();
3336 PathI != PathE; ++PathI) {
3340 Type = (*PathI)->getType();
3352 llvm_unreachable(
"Class must be derived from the passed in base class!");
3367 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3371 LVal.addDecl(Info,
E, FD);
3372 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3380 for (
const auto *
C : IFD->
chain())
3413 if (SOT == SizeOfType::SizeOf)
3414 Size = Info.Ctx.getTypeSizeInChars(
Type);
3416 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3433 LVal.adjustOffsetAndIndex(Info,
E, Adjustment, SizeOfPointee);
3439 int64_t Adjustment) {
3441 APSInt::get(Adjustment));
3456 LVal.Offset += SizeOfComponent;
3458 LVal.addComplex(Info,
E, EltTy, Imag);
3464 uint64_t Size, uint64_t Idx) {
3469 LVal.Offset += SizeOfElement * Idx;
3471 LVal.addVectorElement(Info,
E, EltTy, Size, Idx);
3485 const VarDecl *VD, CallStackFrame *Frame,
3486 unsigned Version,
APValue *&Result) {
3489 bool AllowConstexprUnknown =
3494 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3506 if (!AllowConstexprUnknown || IsLocalVariable) {
3507 if (!Info.checkingPotentialConstantExpression())
3508 Info.FFDiag(
E, diag::note_constexpr_use_uninit_reference);
3518 Result = Frame->getTemporary(VD, Version);
3520 return CheckUninitReference(
true);
3522 if (!isa<ParmVarDecl>(VD)) {
3529 "missing value for local variable");
3530 if (Info.checkingPotentialConstantExpression())
3535 diag::note_unimplemented_constexpr_lambda_feature_ast)
3536 <<
"captures not currently allowed";
3543 if (Info.EvaluatingDecl ==
Base) {
3544 Result = Info.EvaluatingDeclValue;
3545 return CheckUninitReference(
false);
3552 if (isa<ParmVarDecl>(VD)) {
3553 if (AllowConstexprUnknown) {
3560 if (!Info.checkingPotentialConstantExpression() ||
3561 !Info.CurrentCall->Callee ||
3563 if (Info.getLangOpts().CPlusPlus11) {
3564 Info.FFDiag(
E, diag::note_constexpr_function_param_value_unknown)
3585 if (!
Init && !AllowConstexprUnknown) {
3588 if (!Info.checkingPotentialConstantExpression()) {
3589 Info.FFDiag(
E, diag::note_constexpr_var_init_unknown, 1)
3600 if (
Init &&
Init->isValueDependent()) {
3607 if (!Info.checkingPotentialConstantExpression()) {
3608 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
3609 ? diag::note_constexpr_ltor_non_constexpr
3610 : diag::note_constexpr_ltor_non_integral, 1)
3624 Info.FFDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3640 !AllowConstexprUnknown) ||
3641 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3644 Info.CCEDiag(
E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3654 Info.FFDiag(
E, diag::note_constexpr_var_init_weak) << VD;
3661 if (!Result && !AllowConstexprUnknown)
3664 return CheckUninitReference(
false);
3675 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3679 llvm_unreachable(
"base class missing from derived class's bases list");
3685 assert(!isa<SourceLocExpr>(Lit) &&
3686 "SourceLocExpr should have already been converted to a StringLiteral");
3689 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3691 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3692 assert(Index <= Str.size() &&
"Index too large");
3693 return APSInt::getUnsigned(Str.c_str()[Index]);
3696 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3697 Lit = PE->getFunctionName();
3700 Info.Ctx.getAsConstantArrayType(S->getType());
3701 assert(CAT &&
"string literal isn't an array");
3703 assert(CharType->
isIntegerType() &&
"unexpected character type");
3706 if (Index < S->getLength())
3707 Value = S->getCodeUnit(Index);
3719 AllocType.isNull() ? S->getType() : AllocType);
3720 assert(CAT &&
"string literal isn't an array");
3722 assert(CharType->
isIntegerType() &&
"unexpected character type");
3726 std::min(S->getLength(), Elts), Elts);
3729 if (Result.hasArrayFiller())
3731 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3732 Value = S->getCodeUnit(I);
3739 unsigned Size = Array.getArraySize();
3740 assert(Index < Size);
3743 unsigned OldElts = Array.getArrayInitializedElts();
3744 unsigned NewElts = std::max(Index+1, OldElts * 2);
3745 NewElts = std::min(Size, std::max(NewElts, 8u));
3749 for (
unsigned I = 0; I != OldElts; ++I)
3751 for (
unsigned I = OldElts; I != NewElts; ++I)
3755 Array.swap(NewValue);
3776 for (
auto *Field : RD->
fields())
3777 if (!Field->isUnnamedBitField() &&
3781 for (
auto &BaseSpec : RD->
bases())
3799 for (
auto *Field : RD->
fields()) {
3804 if (Field->isMutable() &&
3806 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3807 Info.Note(Field->getLocation(), diag::note_declared_at);
3815 for (
auto &BaseSpec : RD->
bases())
3825 bool MutableSubobject =
false) {
3830 switch (Info.IsEvaluatingDecl) {
3831 case EvalInfo::EvaluatingDeclKind::None:
3834 case EvalInfo::EvaluatingDeclKind::Ctor:
3836 if (Info.EvaluatingDecl ==
Base)
3841 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3842 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3843 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3846 case EvalInfo::EvaluatingDeclKind::Dtor:
3851 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3860 llvm_unreachable(
"unknown evaluating decl kind");
3865 return Info.CheckArraySize(
3874struct CompleteObject {
3882 CompleteObject() :
Value(nullptr) {}
3886 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3897 if (!Info.getLangOpts().CPlusPlus14 &&
3898 AK != AccessKinds::AK_IsWithinLifetime)
3903 explicit operator bool()
const {
return !
Type.isNull(); }
3908 bool IsMutable =
false) {
3922template <
typename Sub
objectHandler>
3923static typename SubobjectHandler::result_type
3925 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3928 return handler.failed();
3929 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3930 if (Info.getLangOpts().CPlusPlus11)
3931 Info.FFDiag(
E, Sub.isOnePastTheEnd()
3932 ? diag::note_constexpr_access_past_end
3933 : diag::note_constexpr_access_unsized_array)
3934 << handler.AccessKind;
3937 return handler.failed();
3943 const FieldDecl *VolatileField =
nullptr;
3946 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3957 if (!Info.checkingPotentialConstantExpression())
3958 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
3961 return handler.failed();
3969 Info.isEvaluatingCtorDtor(
3970 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
3971 ConstructionPhase::None) {
3981 if (Info.getLangOpts().CPlusPlus) {
3985 if (VolatileField) {
3988 Decl = VolatileField;
3989 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3991 Loc = VD->getLocation();
3995 if (
auto *
E = Obj.Base.dyn_cast<
const Expr *>())
3998 Info.FFDiag(
E, diag::note_constexpr_access_volatile_obj, 1)
3999 << handler.AccessKind << DiagKind <<
Decl;
4000 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
4002 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
4004 return handler.failed();
4012 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4014 return handler.failed();
4018 if (!handler.found(*O, ObjType))
4030 LastField =
nullptr;
4034 assert(CAT &&
"vla in literal type?");
4035 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4036 if (CAT->
getSize().ule(Index)) {
4039 if (Info.getLangOpts().CPlusPlus11)
4040 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4041 << handler.AccessKind;
4044 return handler.failed();
4051 else if (!
isRead(handler.AccessKind)) {
4053 return handler.failed();
4061 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4063 if (Info.getLangOpts().CPlusPlus11)
4064 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4065 << handler.AccessKind;
4068 return handler.failed();
4074 assert(I == N - 1 &&
"extracting subobject of scalar?");
4084 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4085 unsigned NumElements = VT->getNumElements();
4086 if (Index == NumElements) {
4087 if (Info.getLangOpts().CPlusPlus11)
4088 Info.FFDiag(
E, diag::note_constexpr_access_past_end)
4089 << handler.AccessKind;
4092 return handler.failed();
4095 if (Index > NumElements) {
4096 Info.CCEDiag(
E, diag::note_constexpr_array_index)
4097 << Index << 0 << NumElements;
4098 return handler.failed();
4101 ObjType = VT->getElementType();
4102 assert(I == N - 1 &&
"extracting subobject of scalar?");
4104 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4105 if (Field->isMutable() &&
4106 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4107 Info.FFDiag(
E, diag::note_constexpr_access_mutable, 1)
4108 << handler.AccessKind << Field;
4109 Info.Note(Field->getLocation(), diag::note_declared_at);
4110 return handler.failed();
4120 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4131 Info.FFDiag(
E, diag::note_constexpr_access_inactive_union_member)
4132 << handler.AccessKind << Field << !UnionField << UnionField;
4133 return handler.failed();
4142 if (Field->getType().isVolatileQualified())
4143 VolatileField = Field;
4156struct ExtractSubobjectHandler {
4162 typedef bool result_type;
4163 bool failed() {
return false; }
4183 const CompleteObject &Obj,
4184 const SubobjectDesignator &Sub,
APValue &Result,
4187 ExtractSubobjectHandler Handler = {Info,
E, Result, AK};
4192struct ModifySubobjectHandler {
4197 typedef bool result_type;
4203 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4209 bool failed() {
return false; }
4211 if (!checkConst(SubobjType))
4214 Subobj.
swap(NewVal);
4218 if (!checkConst(SubobjType))
4220 if (!NewVal.
isInt()) {
4229 if (!checkConst(SubobjType))
4237const AccessKinds ModifySubobjectHandler::AccessKind;
4241 const CompleteObject &Obj,
4242 const SubobjectDesignator &Sub,
4244 ModifySubobjectHandler Handler = { Info, NewVal,
E };
4251 const SubobjectDesignator &A,
4252 const SubobjectDesignator &B,
4253 bool &WasArrayIndex) {
4254 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4255 for (; I != N; ++I) {
4259 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4260 WasArrayIndex =
true;
4268 if (A.Entries[I].getAsBaseOrMember() !=
4269 B.Entries[I].getAsBaseOrMember()) {
4270 WasArrayIndex =
false;
4273 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4275 ObjType = FD->getType();
4281 WasArrayIndex =
false;
4288 const SubobjectDesignator &A,
4289 const SubobjectDesignator &B) {
4290 if (A.Entries.size() != B.Entries.size())
4293 bool IsArray = A.MostDerivedIsArrayElement;
4294 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4303 return CommonLength >= A.Entries.size() - IsArray;
4310 if (LVal.InvalidBase) {
4312 return CompleteObject();
4316 if (AK == AccessKinds::AK_Dereference)
4317 Info.FFDiag(
E, diag::note_constexpr_dereferencing_null);
4319 Info.FFDiag(
E, diag::note_constexpr_access_null) << AK;
4320 return CompleteObject();
4323 CallStackFrame *Frame =
nullptr;
4325 if (LVal.getLValueCallIndex()) {
4326 std::tie(Frame, Depth) =
4327 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4329 Info.FFDiag(
E, diag::note_constexpr_lifetime_ended, 1)
4330 << AK << LVal.Base.is<
const ValueDecl*>();
4332 return CompleteObject();
4343 if (Info.getLangOpts().CPlusPlus)
4344 Info.FFDiag(
E, diag::note_constexpr_access_volatile_type)
4348 return CompleteObject();
4353 QualType BaseType = getType(LVal.Base);
4355 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4359 BaseVal = Info.EvaluatingDeclValue;
4362 if (
auto *GD = dyn_cast<MSGuidDecl>(
D)) {
4365 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4366 return CompleteObject();
4370 Info.FFDiag(
E, diag::note_constexpr_unsupported_layout)
4372 return CompleteObject();
4374 return CompleteObject(LVal.Base, &
V, GD->getType());
4378 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(
D)) {
4380 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4381 return CompleteObject();
4383 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4388 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
4390 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4391 return CompleteObject();
4393 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4404 const VarDecl *VD = dyn_cast<VarDecl>(
D);
4411 return CompleteObject();
4414 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4415 bool ConstexprVar =
false;
4416 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4417 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4424 if (IsAccess && isa<ParmVarDecl>(VD)) {
4428 }
else if (Info.getLangOpts().CPlusPlus14 &&
4435 Info.FFDiag(
E, diag::note_constexpr_modify_global);
4436 return CompleteObject();
4439 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4441 return CompleteObject();
4445 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4446 if (Info.getLangOpts().CPlusPlus) {
4447 Info.FFDiag(
E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4448 Info.Note(VD->
getLocation(), diag::note_declared_at);
4452 return CompleteObject();
4454 }
else if (!IsAccess) {
4455 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4457 Info.checkingPotentialConstantExpression() &&
4460 }
else if (IsConstant) {
4464 if (Info.getLangOpts().CPlusPlus) {
4465 Info.CCEDiag(
E, Info.getLangOpts().CPlusPlus11
4466 ? diag::note_constexpr_ltor_non_constexpr
4467 : diag::note_constexpr_ltor_non_integral, 1)
4469 Info.Note(VD->
getLocation(), diag::note_declared_at);
4475 if (Info.getLangOpts().CPlusPlus) {
4476 Info.FFDiag(
E, Info.getLangOpts().CPlusPlus11
4477 ? diag::note_constexpr_ltor_non_constexpr
4478 : diag::note_constexpr_ltor_non_integral, 1)
4480 Info.Note(VD->
getLocation(), diag::note_declared_at);
4484 return CompleteObject();
4493 return CompleteObject();
4498 if (!Info.checkingPotentialConstantExpression()) {
4499 Info.FFDiag(
E, diag::note_constexpr_access_unknown_variable, 1)
4501 Info.Note(VD->getLocation(), diag::note_declared_at);
4503 return CompleteObject();
4506 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4508 Info.FFDiag(
E, diag::note_constexpr_access_deleted_object) << AK;
4509 return CompleteObject();
4511 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4512 LVal.Base.getDynamicAllocType());
4521 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4522 assert(MTE->getStorageDuration() ==
SD_Static &&
4523 "should have a frame for a non-global materialized temporary");
4550 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4553 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4554 Info.FFDiag(
E, diag::note_constexpr_access_static_temporary, 1) << AK;
4555 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4556 return CompleteObject();
4559 BaseVal = MTE->getOrCreateValue(
false);
4560 assert(BaseVal &&
"got reference to unevaluated temporary");
4562 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4578 !CLETy.isConstant(Info.Ctx)) {
4580 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4581 return CompleteObject();
4584 BaseVal = &CLE->getStaticValue();
4587 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4590 Info.FFDiag(
E, diag::note_constexpr_access_unreadable_object)
4593 Info.Ctx.getLValueReferenceType(LValType));
4595 return CompleteObject();
4598 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4599 assert(BaseVal &&
"missing value for temporary");
4610 unsigned VisibleDepth = Depth;
4611 if (llvm::isa_and_nonnull<ParmVarDecl>(
4612 LVal.Base.dyn_cast<
const ValueDecl *>()))
4614 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4615 Info.EvalStatus.HasSideEffects) ||
4616 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4617 return CompleteObject();
4619 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4638 const LValue &LVal,
APValue &RVal,
4639 bool WantObjectRepresentation =
false) {
4640 if (LVal.Designator.Invalid)
4649 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4650 if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4653 assert(LVal.Designator.Entries.size() <= 1 &&
4654 "Can only read characters from string literals");
4655 if (LVal.Designator.Entries.empty()) {
4662 if (LVal.Designator.isOnePastTheEnd()) {
4663 if (Info.getLangOpts().CPlusPlus11)
4664 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4669 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4676 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4682 if (LVal.Designator.Invalid)
4685 if (!Info.getLangOpts().CPlusPlus14) {
4695struct CompoundAssignSubobjectHandler {
4704 typedef bool result_type;
4709 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4715 bool failed() {
return false; }
4719 return found(Subobj.
getInt(), SubobjType);
4721 return found(Subobj.
getFloat(), SubobjType);
4728 return foundPointer(Subobj, SubobjType);
4730 return foundVector(Subobj, SubobjType);
4732 Info.FFDiag(
E, diag::note_constexpr_access_uninit)
4744 if (!checkConst(SubobjType))
4755 if (!checkConst(SubobjType))
4774 Info.Ctx.getLangOpts());
4777 PromotedLHSType, FValue) &&
4787 return checkConst(SubobjType) &&
4794 if (!checkConst(SubobjType))
4802 (Opcode != BO_Add && Opcode != BO_Sub)) {
4808 if (Opcode == BO_Sub)
4812 LVal.setFrom(Info.Ctx, Subobj);
4815 LVal.moveInto(Subobj);
4821const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4826 const LValue &LVal,
QualType LValType,
4830 if (LVal.Designator.Invalid)
4833 if (!Info.getLangOpts().CPlusPlus14) {
4839 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
4841 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4845struct IncDecSubobjectHandler {
4851 typedef bool result_type;
4856 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
4862 bool failed() {
return false; }
4873 return found(Subobj.
getInt(), SubobjType);
4875 return found(Subobj.
getFloat(), SubobjType);
4885 return foundPointer(Subobj, SubobjType);
4893 if (!checkConst(SubobjType))
4915 bool WasNegative =
Value.isNegative();
4919 if (!WasNegative &&
Value.isNegative() &&
E->canOverflow()) {
4926 if (WasNegative && !
Value.isNegative() &&
E->canOverflow()) {
4927 unsigned BitWidth =
Value.getBitWidth();
4928 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4929 ActualValue.setBit(BitWidth);
4936 if (!checkConst(SubobjType))
4943 APFloat::opStatus St;
4945 St =
Value.add(One, RM);
4947 St =
Value.subtract(One, RM);
4951 if (!checkConst(SubobjType))
4963 LVal.setFrom(Info.Ctx, Subobj);
4967 LVal.moveInto(Subobj);
4976 if (LVal.Designator.Invalid)
4979 if (!Info.getLangOpts().CPlusPlus14) {
4986 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(
E), AK, Old};
4987 return Obj &&
findSubobject(Info,
E, Obj, LVal.Designator, Handler);
4993 if (Object->getType()->isPointerType() && Object->isPRValue())
4996 if (Object->isGLValue())
4999 if (Object->getType()->isLiteralType(Info.Ctx))
5002 if (Object->getType()->isRecordType() && Object->isPRValue())
5005 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
5024 bool IncludeMember =
true) {
5031 if (!MemPtr.getDecl()) {
5037 if (MemPtr.isDerivedMember()) {
5044 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5045 LV.Designator.Entries.size()) {
5049 unsigned PathLengthToMember =
5050 LV.Designator.Entries.size() - MemPtr.Path.size();
5051 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5053 LV.Designator.Entries[PathLengthToMember + I]);
5070 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5071 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5072 : LV.Designator.MostDerivedType->getAsCXXRecordDecl();
5073 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5081 PathLengthToMember))
5083 }
else if (!MemPtr.Path.empty()) {
5085 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5086 MemPtr.Path.size() + IncludeMember);
5092 assert(RD &&
"member pointer access on non-class-type expression");
5094 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5102 MemPtr.getContainingRecord()))
5107 if (IncludeMember) {
5108 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5112 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5116 llvm_unreachable(
"can't construct reference to bound member function");
5120 return MemPtr.getDecl();
5126 bool IncludeMember =
true) {
5130 if (Info.noteFailure()) {
5138 BO->
getRHS(), IncludeMember);
5145 SubobjectDesignator &
D = Result.Designator;
5146 if (
D.Invalid || !Result.checkNullPointer(Info,
E,
CSK_Derived))
5153 auto InvalidCast = [&]() {
5154 if (!Info.checkingPotentialConstantExpression() ||
5155 !Result.AllowConstexprUnknown) {
5156 Info.CCEDiag(
E, diag::note_constexpr_invalid_downcast)
5157 <<
D.MostDerivedType << TargetQT;
5163 if (
D.MostDerivedPathLength +
E->path_size() >
D.Entries.size())
5164 return InvalidCast();
5168 unsigned NewEntriesSize =
D.Entries.size() -
E->path_size();
5171 if (NewEntriesSize ==
D.MostDerivedPathLength)
5172 FinalType =
D.MostDerivedType->getAsCXXRecordDecl();
5174 FinalType = getAsBaseClass(
D.Entries[NewEntriesSize - 1]);
5176 return InvalidCast();
5188 if (!Result.isAbsent())
5192 if (RD->isInvalidDecl()) {
5196 if (RD->isUnion()) {
5201 std::distance(RD->field_begin(), RD->field_end()));
5205 End = RD->bases_end();
5206 I != End; ++I, ++Index)
5210 for (
const auto *I : RD->fields()) {
5211 if (I->isUnnamedBitField())
5214 I->getType(), Result.getStructField(I->getFieldIndex()));
5222 if (Result.hasArrayFiller())
5234enum EvalStmtResult {
5254 assert(
Init->isGLValue() &&
D->getType()->isReferenceType());
5263 if (!Result.Designator.Invalid && Result.Designator.isOnePastTheEnd()) {
5269 Result.moveInto(Val);
5281 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5282 ScopeKind::Block, Result);
5287 return Info.noteSideEffect();
5311 bool EvaluateConditionDecl =
false) {
5313 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
5317 EvaluateConditionDecl && DD)
5327 if (
auto *VD = BD->getHoldingVar())
5335 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5344 if (Info.noteSideEffect())
5346 assert(
E->
containsErrors() &&
"valid value-dependent expression should never "
5347 "reach invalid code path.");
5353 const Expr *Cond,
bool &Result) {
5356 FullExpressionRAII
Scope(Info);
5363 return Scope.destroy();
5376struct TempVersionRAII {
5377 CallStackFrame &Frame;
5379 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5380 Frame.pushTempVersion();
5383 ~TempVersionRAII() {
5384 Frame.popTempVersion();
5398 const Stmt *LoopOrSwitch,
5400 EvalStmtResult &ESR) {
5401 bool IsSwitch = isa<SwitchStmt>(LoopOrSwitch);
5404 if (!IsSwitch && ESR == ESR_Succeeded) {
5409 if (ESR != ESR_Break && ESR != ESR_Continue)
5413 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5414 const Stmt *StackTop = Info.BreakContinueStack.back();
5415 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5416 Info.BreakContinueStack.pop_back();
5417 if (ESR == ESR_Break)
5418 ESR = ESR_Succeeded;
5423 for (BlockScopeRAII *S : Scopes) {
5424 if (!S->destroy()) {
5436 BlockScopeRAII
Scope(Info);
5438 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5439 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5448 BlockScopeRAII
Scope(Info);
5455 if (ESR != ESR_Succeeded) {
5456 if (ESR != ESR_Failed && !
Scope.destroy())
5462 FullExpressionRAII CondScope(Info);
5477 if (!CondScope.destroy())
5486 if (isa<DefaultStmt>(SC)) {
5491 const CaseStmt *CS = cast<CaseStmt>(SC);
5502 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5506 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5513 llvm_unreachable(
"Should have been converted to Succeeded");
5519 case ESR_CaseNotFound:
5522 Info.FFDiag(
Found->getBeginLoc(),
5523 diag::note_constexpr_stmt_expr_unsupported);
5526 llvm_unreachable(
"Invalid EvalStmtResult!");
5536 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5546 if (!Info.nextStep(S))
5552 switch (S->getStmtClass()) {
5553 case Stmt::CompoundStmtClass:
5557 case Stmt::LabelStmtClass:
5558 case Stmt::AttributedStmtClass:
5559 case Stmt::DoStmtClass:
5562 case Stmt::CaseStmtClass:
5563 case Stmt::DefaultStmtClass:
5568 case Stmt::IfStmtClass: {
5571 const IfStmt *IS = cast<IfStmt>(S);
5575 BlockScopeRAII
Scope(Info);
5581 if (ESR != ESR_CaseNotFound) {
5582 assert(ESR != ESR_Succeeded);
5593 if (ESR == ESR_Failed)
5595 if (ESR != ESR_CaseNotFound)
5596 return Scope.destroy() ? ESR : ESR_Failed;
5598 return ESR_CaseNotFound;
5601 if (ESR == ESR_Failed)
5603 if (ESR != ESR_CaseNotFound)
5604 return Scope.destroy() ? ESR : ESR_Failed;
5605 return ESR_CaseNotFound;
5608 case Stmt::WhileStmtClass: {
5609 EvalStmtResult ESR =
5613 if (ESR != ESR_Continue)
5618 case Stmt::ForStmtClass: {
5619 const ForStmt *FS = cast<ForStmt>(S);
5620 BlockScopeRAII
Scope(Info);
5624 if (
const Stmt *
Init = FS->getInit()) {
5626 if (ESR != ESR_CaseNotFound) {
5627 assert(ESR != ESR_Succeeded);
5632 EvalStmtResult ESR =
5636 if (ESR != ESR_Continue)
5638 if (
const auto *Inc = FS->getInc()) {
5639 if (Inc->isValueDependent()) {
5643 FullExpressionRAII IncScope(Info);
5651 case Stmt::DeclStmtClass: {
5654 const DeclStmt *DS = cast<DeclStmt>(S);
5655 for (
const auto *
D : DS->
decls()) {
5656 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
5659 if (VD->hasLocalStorage() && !VD->getInit())
5667 return ESR_CaseNotFound;
5671 return ESR_CaseNotFound;
5675 switch (S->getStmtClass()) {
5677 if (
const Expr *
E = dyn_cast<Expr>(S)) {
5686 FullExpressionRAII
Scope(Info);
5690 return ESR_Succeeded;
5693 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5696 case Stmt::NullStmtClass:
5697 return ESR_Succeeded;
5699 case Stmt::DeclStmtClass: {
5700 const DeclStmt *DS = cast<DeclStmt>(S);
5701 for (
const auto *
D : DS->
decls()) {
5702 const VarDecl *VD = dyn_cast_or_null<VarDecl>(
D);
5706 FullExpressionRAII
Scope(Info);
5708 !Info.noteFailure())
5710 if (!
Scope.destroy())
5713 return ESR_Succeeded;
5716 case Stmt::ReturnStmtClass: {
5717 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5718 FullExpressionRAII
Scope(Info);
5727 :
Evaluate(Result.Value, Info, RetExpr)))
5729 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5732 case Stmt::CompoundStmtClass: {
5733 BlockScopeRAII
Scope(Info);
5736 for (
const auto *BI : CS->
body()) {
5737 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5738 if (ESR == ESR_Succeeded)
5740 else if (ESR != ESR_CaseNotFound) {
5741 if (ESR != ESR_Failed && !
Scope.destroy())
5747 return ESR_CaseNotFound;
5748 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5751 case Stmt::IfStmtClass: {
5752 const IfStmt *IS = cast<IfStmt>(S);
5755 BlockScopeRAII
Scope(Info);
5758 if (ESR != ESR_Succeeded) {
5759 if (ESR != ESR_Failed && !
Scope.destroy())
5769 if (!Info.InConstantContext)
5776 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5777 if (ESR != ESR_Succeeded) {
5778 if (ESR != ESR_Failed && !
Scope.destroy())
5783 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5786 case Stmt::WhileStmtClass: {
5787 const WhileStmt *WS = cast<WhileStmt>(S);
5789 BlockScopeRAII
Scope(Info);
5801 if (ESR != ESR_Continue) {
5802 if (ESR != ESR_Failed && !
Scope.destroy())
5806 if (!
Scope.destroy())
5809 return ESR_Succeeded;
5812 case Stmt::DoStmtClass: {
5813 const DoStmt *DS = cast<DoStmt>(S);
5819 if (ESR != ESR_Continue)
5828 FullExpressionRAII CondScope(Info);
5830 !CondScope.destroy())
5833 return ESR_Succeeded;
5836 case Stmt::ForStmtClass: {
5837 const ForStmt *FS = cast<ForStmt>(S);
5838 BlockScopeRAII ForScope(Info);
5839 if (FS->getInit()) {
5840 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5841 if (ESR != ESR_Succeeded) {
5842 if (ESR != ESR_Failed && !ForScope.destroy())
5848 BlockScopeRAII IterScope(Info);
5849 bool Continue =
true;
5850 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5851 FS->getCond(), Continue))
5855 if (!IterScope.destroy())
5863 if (ESR != ESR_Continue) {
5864 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5869 if (
const auto *Inc = FS->getInc()) {
5870 if (Inc->isValueDependent()) {
5874 FullExpressionRAII IncScope(Info);
5880 if (!IterScope.destroy())
5883 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5886 case Stmt::CXXForRangeStmtClass: {
5888 BlockScopeRAII
Scope(Info);
5891 if (FS->getInit()) {
5892 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5893 if (ESR != ESR_Succeeded) {
5894 if (ESR != ESR_Failed && !
Scope.destroy())
5901 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5902 if (ESR != ESR_Succeeded) {
5903 if (ESR != ESR_Failed && !
Scope.destroy())
5910 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5915 if (ESR != ESR_Succeeded) {
5916 if (ESR != ESR_Failed && !
Scope.destroy())
5921 if (ESR != ESR_Succeeded) {
5922 if (ESR != ESR_Failed && !
Scope.destroy())
5930 if (FS->getCond()->isValueDependent()) {
5935 bool Continue =
true;
5936 FullExpressionRAII CondExpr(Info);
5944 BlockScopeRAII InnerScope(Info);
5945 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5946 if (ESR != ESR_Succeeded) {
5947 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5956 if (ESR != ESR_Continue) {
5957 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5961 if (FS->getInc()->isValueDependent()) {
5970 if (!InnerScope.destroy())
5974 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5977 case Stmt::SwitchStmtClass:
5980 case Stmt::ContinueStmtClass:
5981 case Stmt::BreakStmtClass: {
5982 auto *B = cast<LoopControlStmt>(S);
5983 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
5984 return isa<ContinueStmt>(S) ? ESR_Continue : ESR_Break;
5987 case Stmt::LabelStmtClass:
5988 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5990 case Stmt::AttributedStmtClass: {
5991 const auto *AS = cast<AttributedStmt>(S);
5992 const auto *SS = AS->getSubStmt();
5993 MSConstexprContextRAII ConstexprContext(
5994 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5995 isa<ReturnStmt>(SS));
5997 auto LO = Info.getASTContext().getLangOpts();
5998 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5999 for (
auto *
Attr : AS->getAttrs()) {
6000 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6004 auto *Assumption = AA->getAssumption();
6005 if (Assumption->isValueDependent())
6008 if (Assumption->HasSideEffects(Info.getASTContext()))
6015 Info.CCEDiag(Assumption->getExprLoc(),
6016 diag::note_constexpr_assumption_failed);
6025 case Stmt::CaseStmtClass:
6026 case Stmt::DefaultStmtClass:
6027 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
6028 case Stmt::CXXTryStmtClass:
6030 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
6040 bool IsValueInitialization) {
6047 if (!CD->
isConstexpr() && !IsValueInitialization) {
6048 if (Info.getLangOpts().CPlusPlus11) {
6051 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
6053 Info.Note(CD->
getLocation(), diag::note_declared_at);
6055 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
6069 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6077 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6084 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
6086 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6089 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6095 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6105 StringRef Name = DiagDecl->
getName();
6107 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6109 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6114 if (Info.getLangOpts().CPlusPlus11) {
6117 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6118 if (CD && CD->isInheritingConstructor()) {
6119 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6120 if (!Inherited->isConstexpr())
6121 DiagDecl = CD = Inherited;
6127 if (CD && CD->isInheritingConstructor())
6128 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6129 << CD->getInheritedConstructor().getConstructor()->
getParent();
6131 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6133 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6135 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6141struct CheckDynamicTypeHandler {
6143 typedef bool result_type;
6144 bool failed() {
return false; }
6147 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
6155 if (
This.Designator.Invalid)
6167 if (
This.Designator.isOnePastTheEnd() ||
6168 This.Designator.isMostDerivedAnUnsizedArray()) {
6169 Info.FFDiag(
E,
This.Designator.isOnePastTheEnd()
6170 ? diag::note_constexpr_access_past_end
6171 : diag::note_constexpr_access_unsized_array)
6174 }
else if (Polymorphic) {
6177 if (!Info.checkingPotentialConstantExpression() ||
6178 !
This.AllowConstexprUnknown) {
6182 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6183 Info.FFDiag(
E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6191 CheckDynamicTypeHandler Handler{AK};
6214 unsigned PathLength) {
6215 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6216 Designator.Entries.size() &&
"invalid path length");
6217 return (PathLength ==
Designator.MostDerivedPathLength)
6218 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6219 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6232 return std::nullopt;
6234 if (
This.Designator.Invalid)
6235 return std::nullopt;
6244 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6247 return std::nullopt;
6255 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6256 PathLength <=
Path.size(); ++PathLength) {
6257 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6258 Path.slice(0, PathLength))) {
6259 case ConstructionPhase::Bases:
6260 case ConstructionPhase::DestroyingBases:
6265 case ConstructionPhase::None:
6266 case ConstructionPhase::AfterBases:
6267 case ConstructionPhase::AfterFields:
6268 case ConstructionPhase::Destroying:
6280 return std::nullopt;
6298 unsigned PathLength = DynType->PathLength;
6299 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6302 Found->getCorrespondingMethodDeclaredInClass(
Class,
false);
6312 if (Callee->isPureVirtual()) {
6313 Info.FFDiag(
E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6314 Info.Note(Callee->getLocation(), diag::note_declared_at);
6320 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6321 Found->getReturnType())) {
6322 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6323 for (
unsigned CovariantPathLength = PathLength + 1;
6324 CovariantPathLength !=
This.Designator.Entries.size();
6325 ++CovariantPathLength) {
6329 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6330 if (Next && !Info.Ctx.hasSameUnqualifiedType(
6331 Next->getReturnType(), CovariantAdjustmentPath.back()))
6332 CovariantAdjustmentPath.push_back(Next->getReturnType());
6334 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6335 CovariantAdjustmentPath.back()))
6336 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6352 assert(Result.isLValue() &&
6353 "unexpected kind of APValue for covariant return");
6354 if (Result.isNullPointer())
6358 LVal.setFrom(Info.Ctx, Result);
6361 for (
unsigned I = 1; I !=
Path.size(); ++I) {
6363 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6364 if (OldClass != NewClass &&
6367 OldClass = NewClass;
6370 LVal.moveInto(Result);
6379 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6381 return BaseSpec.getAccessSpecifier() ==
AS_public;
6383 llvm_unreachable(
"Base is not a direct base of Derived");
6393 SubobjectDesignator &
D = Ptr.Designator;
6405 std::optional<DynamicType> DynType =
6416 const CXXRecordDecl *
C =
E->getTypeAsWritten()->getPointeeCXXRecordDecl();
6417 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6425 Ptr.setNull(Info.Ctx,
E->
getType());
6432 DynType->Type->isDerivedFrom(
C)))
6434 else if (!Paths || Paths->begin() == Paths->end())
6436 else if (Paths->isAmbiguous(CQT))
6439 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6442 Info.FFDiag(
E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6443 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6444 << Info.Ctx.getCanonicalTagType(DynType->Type)
6452 for (
int PathLength = Ptr.Designator.Entries.size();
6453 PathLength >= (
int)DynType->PathLength; --PathLength) {
6458 if (PathLength > (
int)DynType->PathLength &&
6461 return RuntimeCheckFailed(
nullptr);
6468 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6481 return RuntimeCheckFailed(&Paths);
6485struct StartLifetimeOfUnionMemberHandler {
6487 const Expr *LHSExpr;
6490 bool Failed =
false;
6493 typedef bool result_type;
6494 bool failed() {
return Failed; }
6510 }
else if (DuringInit) {
6514 Info.FFDiag(LHSExpr,
6515 diag::note_constexpr_union_member_change_during_init);
6524 llvm_unreachable(
"wrong value kind for union object");
6527 llvm_unreachable(
"wrong value kind for union object");
6532const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6539 const Expr *LHSExpr,
6540 const LValue &LHS) {
6541 if (LHS.InvalidBase || LHS.Designator.Invalid)
6547 unsigned PathLength = LHS.Designator.Entries.size();
6548 for (
const Expr *
E = LHSExpr;
E !=
nullptr;) {
6550 if (
auto *ME = dyn_cast<MemberExpr>(
E)) {
6551 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6554 if (!FD || FD->getType()->isReferenceType())
6558 if (FD->getParent()->isUnion()) {
6563 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6564 if (!RD || RD->hasTrivialDefaultConstructor())
6565 UnionPathLengths.push_back({PathLength - 1, FD});
6571 LHS.Designator.Entries[PathLength]
6572 .getAsBaseOrMember().getPointer()));
6576 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(
E)) {
6578 auto *
Base = ASE->getBase()->IgnoreImplicit();
6579 if (!
Base->getType()->isArrayType())
6585 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
6587 E = ICE->getSubExpr();
6588 if (ICE->getCastKind() == CK_NoOp)
6590 if (ICE->getCastKind() != CK_DerivedToBase &&
6591 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6595 if (Elt->isVirtual()) {
6604 LHS.Designator.Entries[PathLength]
6605 .getAsBaseOrMember().getPointer()));
6615 if (UnionPathLengths.empty())
6620 CompleteObject Obj =
6624 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6625 llvm::reverse(UnionPathLengths)) {
6627 SubobjectDesignator
D = LHS.Designator;
6628 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6630 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base,
D.Entries) ==
6631 ConstructionPhase::AfterBases;
6632 StartLifetimeOfUnionMemberHandler StartLifetime{
6633 Info, LHSExpr, LengthAndField.second, DuringInit};
6642 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6643 APValue **EvaluatedArg =
nullptr) {
6650 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6651 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6652 ScopeKind::Call, LV);
6658 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6659 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6672 bool RightToLeft =
false,
6673 LValue *ObjectArg =
nullptr) {
6675 llvm::SmallBitVector ForbiddenNullArgs;
6676 if (Callee->hasAttr<NonNullAttr>()) {
6677 ForbiddenNullArgs.resize(Args.size());
6678 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6679 if (!
Attr->args_size()) {
6680 ForbiddenNullArgs.set();
6683 for (
auto Idx :
Attr->args()) {
6684 unsigned ASTIdx = Idx.getASTIndex();
6685 if (ASTIdx >= Args.size())
6687 ForbiddenNullArgs[ASTIdx] =
true;
6691 for (
unsigned I = 0; I < Args.size(); I++) {
6692 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6694 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6695 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6700 if (!Info.noteFailure())
6705 ObjectArg->setFrom(Info.Ctx, *That);
6714 bool CopyObjectRepresentation) {
6716 CallStackFrame *Frame = Info.CurrentCall;
6717 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6725 RefLValue.setFrom(Info.Ctx, *RefValue);
6728 CopyObjectRepresentation);
6734 const LValue *ObjectArg,
const Expr *
E,
6736 const Stmt *Body, EvalInfo &Info,
6737 APValue &Result,
const LValue *ResultSlot) {
6738 if (!Info.CheckCallLimit(CallLoc))
6767 ObjectArg->moveInto(Result);
6776 if (!Info.checkingPotentialConstantExpression())
6778 Frame.LambdaThisCaptureField);
6783 if (ESR == ESR_Succeeded) {
6784 if (Callee->getReturnType()->isVoidType())
6786 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6788 return ESR == ESR_Returned;
6795 EvalInfo &Info,
APValue &Result) {
6797 if (!Info.CheckCallLimit(CallLoc))
6802 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6806 EvalInfo::EvaluatingConstructorRAII EvalObj(
6808 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
6820 if ((*I)->getInit()->isValueDependent()) {
6824 FullExpressionRAII InitScope(Info);
6826 !InitScope.destroy())
6849 if (!Result.hasValue()) {
6862 BlockScopeRAII LifetimeExtendedScope(Info);
6865 unsigned BasesSeen = 0;
6875 assert(
Indirect &&
"fields out of order?");
6881 assert(FieldIt != RD->
field_end() &&
"missing field?");
6882 if (!FieldIt->isUnnamedBitField())
6885 Result.getStructField(FieldIt->getFieldIndex()));
6890 LValue Subobject =
This;
6891 LValue SubobjectParent =
This;
6896 if (I->isBaseInitializer()) {
6897 QualType BaseType(I->getBaseClass(), 0);
6901 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6902 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6903 "base class initializers not in expected order");
6909 Value = &Result.getStructBase(BasesSeen++);
6910 }
else if ((FD = I->getMember())) {
6915 Value = &Result.getUnionValue();
6917 SkipToField(FD,
false);
6923 auto IndirectFieldChain = IFD->chain();
6924 for (
auto *
C : IndirectFieldChain) {
6925 FD = cast<FieldDecl>(
C);
6933 (
Value->isUnion() &&
6946 if (
C == IndirectFieldChain.back())
6947 SubobjectParent = Subobject;
6953 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6954 SkipToField(FD,
true);
6959 llvm_unreachable(
"unknown base initializer kind");
6966 if (
Init->isValueDependent()) {
6970 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6971 isa<CXXDefaultInitExpr>(
Init));
6972 FullExpressionRAII InitScope(Info);
6978 if (!Info.noteFailure())
6987 if (!Info.noteFailure())
6995 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6996 EvalObj.finishedConstructingBases();
7001 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7002 if (!FieldIt->isUnnamedBitField())
7005 Result.getStructField(FieldIt->getFieldIndex()));
7009 EvalObj.finishedConstructingFields();
7013 LifetimeExtendedScope.destroy();
7019 EvalInfo &Info,
APValue &Result) {
7020 CallScopeRAII CallScope(Info);
7026 CallScope.destroy();
7038 This.moveInto(Printable);
7040 diag::note_constexpr_destroy_out_of_lifetime)
7041 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
7057 LValue ElemLV =
This;
7058 ElemLV.addArray(Info, &LocE, CAT);
7065 if (Size && Size >
Value.getArrayInitializedElts())
7070 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7071 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7084 if (
T.isDestructedType()) {
7086 diag::note_constexpr_unsupported_destruction)
7096 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7121 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7130 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7135 EvalInfo::EvaluatingDestructorRAII EvalObj(
7137 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7138 if (!EvalObj.DidInsert) {
7145 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7165 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7166 if (FD->isUnnamedBitField())
7169 LValue Subobject =
This;
7173 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7180 EvalObj.startedDestroyingBases();
7187 LValue Subobject =
This;
7192 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7197 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7205struct DestroyObjectHandler {
7211 typedef bool result_type;
7212 bool failed() {
return false; }
7218 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7222 Info.FFDiag(
E, diag::note_constexpr_destroy_complex_elem);
7243 if (Info.EvalStatus.HasSideEffects)
7254 if (Info.checkingPotentialConstantExpression() ||
7255 Info.SpeculativeEvaluationDepth)
7259 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7261 Info.FFDiag(
E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7262 ? diag::note_constexpr_new_untyped
7263 : diag::note_constexpr_new);
7267 QualType ElemType = Caller.ElemType;
7270 diag::note_constexpr_new_not_complete_object_type)
7278 bool IsNothrow =
false;
7279 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I) {
7287 APInt Size, Remainder;
7288 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7289 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7290 if (Remainder != 0) {
7292 Info.FFDiag(
E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7293 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7297 if (!Info.CheckArraySize(
E->
getBeginLoc(), ByteSize.getActiveBits(),
7298 Size.getZExtValue(), !IsNothrow)) {
7300 Result.setNull(Info.Ctx,
E->
getType());
7306 QualType AllocType = Info.Ctx.getConstantArrayType(
7307 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
7308 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType, Result);
7310 Result.addArray(Info,
E, cast<ConstantArrayType>(AllocType));
7317 return DD->isVirtual();
7324 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7335 DynAlloc::Kind DeallocKind) {
7336 auto PointerAsString = [&] {
7337 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7342 Info.FFDiag(
E, diag::note_constexpr_delete_not_heap_alloc)
7343 << PointerAsString();
7346 return std::nullopt;
7349 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7351 Info.FFDiag(
E, diag::note_constexpr_double_delete);
7352 return std::nullopt;
7355 if (DeallocKind != (*Alloc)->getKind()) {
7357 Info.FFDiag(
E, diag::note_constexpr_new_delete_mismatch)
7358 << DeallocKind << (*Alloc)->getKind() << AllocType;
7360 return std::nullopt;
7363 bool Subobject =
false;
7364 if (DeallocKind == DynAlloc::New) {
7365 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7366 Pointer.Designator.isOnePastTheEnd();
7368 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7369 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7372 Info.FFDiag(
E, diag::note_constexpr_delete_subobject)
7373 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7374 return std::nullopt;
7382 if (Info.checkingPotentialConstantExpression() ||
7383 Info.SpeculativeEvaluationDepth)
7387 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7395 for (
unsigned I = 1, N =
E->getNumArgs(); I != N; ++I)
7398 if (
Pointer.Designator.Invalid)
7403 if (
Pointer.isNullPointer()) {
7404 Info.CCEDiag(
E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7420class BitCastBuffer {
7428 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7429 "Need at least 8 bit unsigned char");
7431 bool TargetIsLittleEndian;
7434 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
7435 : Bytes(Width.getQuantity()),
7436 TargetIsLittleEndian(TargetIsLittleEndian) {}
7440 for (
CharUnits I = Offset,
E = Offset + Width; I !=
E; ++I) {
7443 if (!Bytes[I.getQuantity()])
7445 Output.push_back(*Bytes[I.getQuantity()]);
7447 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7448 std::reverse(Output.begin(), Output.end());
7453 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7454 std::reverse(Input.begin(), Input.end());
7457 for (
unsigned char Byte : Input) {
7458 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7459 Bytes[Offset.getQuantity() + Index] = Byte;
7464 size_t size() {
return Bytes.size(); }
7469class APValueToBufferConverter {
7471 BitCastBuffer Buffer;
7474 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7477 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7486 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7499 return visitInt(Val.
getInt(), Ty, Offset);
7501 return visitFloat(Val.
getFloat(), Ty, Offset);
7503 return visitArray(Val, Ty, Offset);
7505 return visitRecord(Val, Ty, Offset);
7507 return visitVector(Val, Ty, Offset);
7511 return visitComplex(Val, Ty, Offset);
7519 diag::note_constexpr_bit_cast_unsupported_type)
7525 llvm_unreachable(
"LValue subobject in bit_cast?");
7527 llvm_unreachable(
"Unhandled APValue::ValueKind");
7535 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7536 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7542 if (!
Base.isStruct())
7552 unsigned FieldIdx = 0;
7554 if (FD->isBitField()) {
7556 diag::note_constexpr_bit_cast_unsupported_bitfield);
7562 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7563 "only bit-fields can have sub-char alignment");
7565 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7585 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7587 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7594 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7595 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7606 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7611 Offset + (0 * EltSizeChars)))
7614 Offset + (1 * EltSizeChars)))
7618 Offset + (0 * EltSizeChars)))
7621 Offset + (1 * EltSizeChars)))
7642 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7644 llvm::APInt Res = llvm::APInt::getZero(NElts);
7645 for (
unsigned I = 0; I < NElts; ++I) {
7647 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7648 "bool vector element must be 1-bit unsigned integer!");
7650 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7654 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7655 Buffer.writeObject(Offset, Bytes);
7659 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7660 for (
unsigned I = 0; I < NElts; ++I) {
7661 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7670 APSInt AdjustedVal = Val;
7671 unsigned Width = AdjustedVal.getBitWidth();
7673 Width = Info.Ctx.getTypeSize(Ty);
7674 AdjustedVal = AdjustedVal.extend(Width);
7678 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7679 Buffer.writeObject(Offset, Bytes);
7684 APSInt AsInt(Val.bitcastToAPInt());
7685 return visitInt(AsInt, Ty, Offset);
7689 static std::optional<BitCastBuffer>
7692 APValueToBufferConverter Converter(Info, DstSize, BCE);
7694 return std::nullopt;
7695 return Converter.Buffer;
7700class BufferToAPValueConverter {
7702 const BitCastBuffer &Buffer;
7705 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7707 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7712 std::nullopt_t unsupportedType(
QualType Ty) {
7714 diag::note_constexpr_bit_cast_unsupported_type)
7716 return std::nullopt;
7719 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7721 diag::note_constexpr_bit_cast_unrepresentable_value)
7723 return std::nullopt;
7727 const EnumType *EnumSugar =
nullptr) {
7741 const llvm::fltSemantics &Semantics =
7742 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7743 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7744 assert(NumBits % 8 == 0);
7751 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7754 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7758 if (!IsStdByte && !IsUChar) {
7759 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7761 diag::note_constexpr_bit_cast_indet_dest)
7762 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7763 return std::nullopt;
7769 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7770 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7775 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7776 if (IntWidth != Val.getBitWidth()) {
7777 APSInt Truncated = Val.trunc(IntWidth);
7778 if (Truncated.extend(Val.getBitWidth()) != Val)
7779 return unrepresentableValue(
QualType(
T, 0), Val);
7787 const llvm::fltSemantics &Semantics =
7788 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7799 unsigned NumBases = 0;
7800 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7801 NumBases = CXXRD->getNumBases();
7807 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7808 for (
size_t I = 0,
E = CXXRD->getNumBases(); I !=
E; ++I) {
7812 std::optional<APValue> SubObj = visitType(
7815 return std::nullopt;
7816 ResultVal.getStructBase(I) = *SubObj;
7821 unsigned FieldIdx = 0;
7825 if (FD->isBitField()) {
7827 diag::note_constexpr_bit_cast_unsupported_bitfield);
7828 return std::nullopt;
7832 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7838 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7840 return std::nullopt;
7841 ResultVal.getStructField(FieldIdx) = *SubObj;
7851 assert(!RepresentationType.
isNull() &&
7852 "enum forward decl should be caught by Sema");
7853 const auto *AsBuiltin =
7857 return visit(AsBuiltin, Offset, Ty);
7865 for (
size_t I = 0; I !=
Size; ++I) {
7866 std::optional<APValue> ElementValue =
7869 return std::nullopt;
7870 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7878 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
7881 std::optional<APValue> Values[2];
7882 for (
unsigned I = 0; I != 2; ++I) {
7883 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
7885 return std::nullopt;
7889 return APValue(Values[0]->getInt(), Values[1]->getInt());
7890 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
7900 Elts.reserve(NElts);
7910 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7913 Bytes.reserve(NElts / 8);
7915 return std::nullopt;
7917 APSInt SValInt(NElts,
true);
7918 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7920 for (
unsigned I = 0; I < NElts; ++I) {
7922 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7929 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7930 for (
unsigned I = 0; I < NElts; ++I) {
7931 std::optional<APValue> EltValue =
7932 visitType(EltTy, Offset + I * EltSizeChars);
7934 return std::nullopt;
7935 Elts.push_back(std::move(*EltValue));
7939 return APValue(Elts.data(), Elts.size());
7942 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7943 return unsupportedType(
QualType(Ty, 0));
7950#define TYPE(Class, Base) \
7952 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7953#define ABSTRACT_TYPE(Class, Base)
7954#define NON_CANONICAL_TYPE(Class, Base) \
7956 llvm_unreachable("non-canonical type should be impossible!");
7957#define DEPENDENT_TYPE(Class, Base) \
7960 "dependent types aren't supported in the constant evaluator!");
7961#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7963 llvm_unreachable("either dependent or not canonical!");
7964#include "clang/AST/TypeNodes.inc"
7966 llvm_unreachable(
"Unhandled Type::TypeClass");
7971 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7973 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7981 bool CheckingDest) {
7984 auto diag = [&](
int Reason) {
7986 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7987 << CheckingDest << (Reason == 4) << Reason;
7992 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7993 << NoteTy << Construct << Ty;
8007 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8009 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
8014 if (FD->getType()->isReferenceType())
8016 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
8018 return note(0, FD->getType(), FD->getBeginLoc());
8024 Info, Ctx, CheckingDest))
8039 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_vector)
8050 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_unsupported_type)
8059static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8062 bool DestOK = checkBitCastConstexprEligibilityType(
8064 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8070static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8073 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8074 "no host or target supports non 8-bit chars");
8076 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8080 std::optional<BitCastBuffer> Buffer =
8081 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8086 std::optional<APValue> MaybeDestValue =
8087 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8088 if (!MaybeDestValue)
8091 DestValue = std::move(*MaybeDestValue);
8095static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8098 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8099 "no host or target supports non 8-bit chars");
8101 "LValueToRValueBitcast requires an lvalue operand!");
8103 LValue SourceLValue;
8105 SourceLValue.setFrom(Info.Ctx, SourceValue);
8108 SourceRValue,
true))
8111 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8114template <
class Derived>
8115class ExprEvaluatorBase
8118 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8120 return getDerived().Success(
V,
E);
8122 bool DerivedZeroInitialization(
const Expr *
E) {
8123 return getDerived().ZeroInitialization(
E);
8129 template<
typename ConditionalOperator>
8131 assert(Info.checkingPotentialConstantExpression());
8136 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8137 StmtVisitorTy::Visit(
E->getFalseExpr());
8143 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8145 StmtVisitorTy::Visit(
E->getTrueExpr());
8150 Error(
E, diag::note_constexpr_conditional_never_const);
8154 template<
typename ConditionalOperator>
8158 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8159 CheckPotentialConstantConditional(
E);
8162 if (Info.noteFailure()) {
8163 StmtVisitorTy::Visit(
E->getTrueExpr());
8164 StmtVisitorTy::Visit(
E->getFalseExpr());
8169 Expr *EvalExpr = BoolResult ?
E->getTrueExpr() :
E->getFalseExpr();
8170 return StmtVisitorTy::Visit(EvalExpr);
8176 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8179 return Info.CCEDiag(
E,
D);
8182 bool ZeroInitialization(
const Expr *
E) {
return Error(
E); }
8184 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *
E) {
8185 unsigned BuiltinOp =
E->getBuiltinCallee();
8186 return BuiltinOp != 0 &&
8187 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8191 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8193 EvalInfo &getEvalInfo() {
return Info; }
8202 return Error(
E, diag::note_invalid_subexpr_in_const_expr);
8205 bool VisitStmt(
const Stmt *) {
8206 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8208 bool VisitExpr(
const Expr *
E) {
8213 const auto It =
E->begin();
8214 return StmtVisitorTy::Visit(*It);
8218 return StmtVisitorTy::Visit(
E->getFunctionName());
8221 if (
E->hasAPValueResult())
8222 return DerivedSuccess(
E->getAPValueResult(),
E);
8224 return StmtVisitorTy::Visit(
E->getSubExpr());
8228 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8230 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8232 {
return StmtVisitorTy::Visit(
E->getSubExpr()); }
8234 {
return StmtVisitorTy::Visit(
E->getChosenSubExpr()); }
8236 {
return StmtVisitorTy::Visit(
E->getResultExpr()); }
8238 {
return StmtVisitorTy::Visit(
E->getReplacement()); }
8240 TempVersionRAII RAII(*Info.CurrentCall);
8241 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8242 return StmtVisitorTy::Visit(
E->getExpr());
8245 TempVersionRAII RAII(*Info.CurrentCall);
8249 SourceLocExprScopeGuard Guard(
E, Info.CurrentCall->CurSourceLocExprScope);
8250 return StmtVisitorTy::Visit(
E->getExpr());
8254 FullExpressionRAII
Scope(Info);
8255 return StmtVisitorTy::Visit(
E->getSubExpr()) &&
Scope.destroy();
8261 return StmtVisitorTy::Visit(
E->getSubExpr());
8265 CCEDiag(
E, diag::note_constexpr_invalid_cast)
8266 << diag::ConstexprInvalidCastKind::Reinterpret;
8267 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8270 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8271 CCEDiag(
E, diag::note_constexpr_invalid_cast)
8272 << diag::ConstexprInvalidCastKind::Dynamic;
8273 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8276 return static_cast<Derived*
>(
this)->VisitCastExpr(
E);
8280 switch (
E->getOpcode()) {
8285 VisitIgnoredValue(
E->getLHS());
8286 return StmtVisitorTy::Visit(
E->getRHS());
8296 return DerivedSuccess(Result,
E);
8302 return StmtVisitorTy::Visit(
E->getSemanticForm());
8309 if (!
Evaluate(Info.CurrentCall->createTemporary(
8310 E->getOpaqueValue(),
8311 getStorageType(Info.Ctx,
E->getOpaqueValue()),
8312 ScopeKind::FullExpression, CommonLV),
8313 Info,
E->getCommon()))
8316 return HandleConditionalOperator(
E);
8320 bool IsBcpCall =
false;
8327 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8334 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8337 FoldConstant Fold(Info, IsBcpCall);
8338 if (!HandleConditionalOperator(
E)) {
8339 Fold.keepDiagnostics();
8347 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(
E);
8349 return DerivedSuccess(*
Value,
E);
8351 const Expr *Source =
E->getSourceExpr();
8355 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8358 return StmtVisitorTy::Visit(Source);
8362 for (
const Expr *SemE :
E->semantics()) {
8363 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8367 if (SemE ==
E->getResultExpr())
8372 if (OVE->isUnique())
8376 if (!
Evaluate(Info.CurrentCall->createTemporary(
8377 OVE, getStorageType(Info.Ctx, OVE),
8378 ScopeKind::FullExpression, LV),
8379 Info, OVE->getSourceExpr()))
8381 }
else if (SemE ==
E->getResultExpr()) {
8382 if (!StmtVisitorTy::Visit(SemE))
8394 if (!handleCallExpr(
E, Result,
nullptr))
8396 return DerivedSuccess(Result,
E);
8400 const LValue *ResultSlot) {
8401 CallScopeRAII CallScope(Info);
8407 LValue *
This =
nullptr, ObjectArg;
8408 auto Args =
ArrayRef(
E->getArgs(),
E->getNumArgs());
8409 bool HasQualifier =
false;
8416 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8420 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8422 return Error(Callee);
8424 HasQualifier = ME->hasQualifier();
8425 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8431 Member = dyn_cast<CXXMethodDecl>(
D);
8433 return Error(Callee);
8435 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8436 if (!Info.getLangOpts().CPlusPlus20)
8437 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8441 return Error(Callee);
8448 if (!CalleeLV.getLValueOffset().isZero())
8449 return Error(Callee);
8450 if (CalleeLV.isNullPointer()) {
8451 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8455 FD = dyn_cast_or_null<FunctionDecl>(
8456 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8458 return Error(Callee);
8461 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8468 auto *OCE = dyn_cast<CXXOperatorCallExpr>(
E);
8469 if (OCE && OCE->isAssignmentOp()) {
8470 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8471 Call = Info.CurrentCall->createCall(FD);
8472 bool HasThis =
false;
8473 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8474 HasThis = MD->isImplicitObjectMemberFunction();
8502 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8503 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8507 Args = Args.slice(1);
8515 ClosureClass->
captures().empty() &&
8516 "Number of captures must be zero for conversion to function-ptr");
8527 "A generic lambda's static-invoker function must be a "
8528 "template specialization");
8532 void *InsertPos =
nullptr;
8535 assert(CorrespondingCallOpSpecialization &&
8536 "We must always have a function call operator specialization "
8537 "that corresponds to our static invoker specialization");
8538 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8539 FD = CorrespondingCallOpSpecialization;
8547 Ptr.moveInto(Result);
8548 return CallScope.destroy();
8558 Call = Info.CurrentCall->createCall(FD);
8566 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8567 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8570 CovariantAdjustmentPath);
8573 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8583 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8584 assert(
This &&
"no 'this' pointer for destructor call");
8586 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8587 CallScope.destroy();
8601 Result, ResultSlot))
8604 if (!CovariantAdjustmentPath.empty() &&
8606 CovariantAdjustmentPath))
8609 return CallScope.destroy();
8613 return StmtVisitorTy::Visit(
E->getInitializer());
8616 if (
E->getNumInits() == 0)
8617 return DerivedZeroInitialization(
E);
8618 if (
E->getNumInits() == 1)
8619 return StmtVisitorTy::Visit(
E->getInit(0));
8623 return DerivedZeroInitialization(
E);
8626 return DerivedZeroInitialization(
E);
8629 return DerivedZeroInitialization(
E);
8634 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8635 "missing temporary materialization conversion");
8636 assert(!
E->isArrow() &&
"missing call to bound member function?");
8644 const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl());
8645 if (!FD)
return Error(
E);
8649 "record / field mismatch");
8660 DerivedSuccess(Result,
E);
8670 E->getEncodedElementAccess(Indices);
8671 if (Indices.size() == 1) {
8677 for (
unsigned I = 0; I < Indices.size(); ++I) {
8680 APValue VecResult(Elts.data(), Indices.size());
8681 return DerivedSuccess(VecResult,
E);
8689 switch (
E->getCastKind()) {
8693 case CK_AtomicToNonAtomic: {
8698 if (!
Evaluate(AtomicVal, Info,
E->getSubExpr()))
8700 return DerivedSuccess(AtomicVal,
E);
8704 case CK_UserDefinedConversion:
8705 return StmtVisitorTy::Visit(
E->getSubExpr());
8707 case CK_LValueToRValue: {
8716 return DerivedSuccess(RVal,
E);
8718 case CK_LValueToRValueBitCast: {
8719 APValue DestValue, SourceValue;
8720 if (!
Evaluate(SourceValue, Info,
E->getSubExpr()))
8722 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue,
E))
8724 return DerivedSuccess(DestValue,
E);
8727 case CK_AddressSpaceConversion: {
8731 return DerivedSuccess(
Value,
E);
8739 return VisitUnaryPostIncDec(UO);
8742 return VisitUnaryPostIncDec(UO);
8745 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8755 return DerivedSuccess(RVal, UO);
8768 BlockScopeRAII
Scope(Info);
8773 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8775 Info.FFDiag((*BI)->getBeginLoc(),
8776 diag::note_constexpr_stmt_expr_unsupported);
8779 return this->Visit(FinalExpr) &&
Scope.destroy();
8785 if (ESR != ESR_Succeeded) {
8789 if (ESR != ESR_Failed)
8790 Info.FFDiag((*BI)->getBeginLoc(),
8791 diag::note_constexpr_stmt_expr_unsupported);
8796 llvm_unreachable(
"Return from function from the loop above.");
8800 return StmtVisitorTy::Visit(
E->getSelectedExpr());
8804 void VisitIgnoredValue(
const Expr *
E) {
8809 void VisitIgnoredBaseExpression(
const Expr *
E) {
8814 VisitIgnoredValue(
E);
8824template<
class Derived>
8825class LValueExprEvaluatorBase
8826 :
public ExprEvaluatorBase<Derived> {
8830 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8831 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8838 bool evaluatePointer(
const Expr *
E, LValue &Result) {
8843 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8844 : ExprEvaluatorBaseTy(Info), Result(Result),
8845 InvalidBaseOK(InvalidBaseOK) {}
8848 Result.setFrom(this->Info.Ctx,
V);
8857 EvalOK = evaluatePointer(
E->getBase(), Result);
8864 EvalOK = this->Visit(
E->getBase());
8870 Result.setInvalid(
E);
8875 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(
E->getMemberDecl())) {
8878 "record / field mismatch");
8899 switch (
E->getOpcode()) {
8901 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
8910 switch (
E->getCastKind()) {
8912 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
8914 case CK_DerivedToBase:
8915 case CK_UncheckedDerivedToBase:
8916 if (!this->Visit(
E->getSubExpr()))
8962class LValueExprEvaluator
8963 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8965 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8966 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8979 E, 0, Info.getASTContext().getNextStringLiteralVersion()));
8990 return VisitUnaryPreIncDec(UO);
8993 return VisitUnaryPreIncDec(UO);
8999 switch (
E->getCastKind()) {
9001 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
9003 case CK_LValueBitCast:
9004 this->CCEDiag(
E, diag::note_constexpr_invalid_cast)
9005 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9006 << Info.Ctx.getLangOpts().CPlusPlus;
9007 if (!Visit(
E->getSubExpr()))
9009 Result.Designator.setInvalid();
9012 case CK_BaseToDerived:
9013 if (!Visit(
E->getSubExpr()))
9018 if (!Visit(
E->getSubExpr()))
9029 bool LValueToRValueConversion) {
9033 assert(Info.CurrentCall->This ==
nullptr &&
9034 "This should not be set for a static call operator");
9042 if (Self->getType()->isReferenceType()) {
9043 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
9045 Result.setFrom(Info.Ctx, *RefValue);
9047 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
9048 CallStackFrame *Frame =
9049 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9051 unsigned Version = Info.CurrentCall->Arguments.Version;
9052 Result.set({VD, Frame->Index, Version});
9055 Result = *Info.CurrentCall->This;
9065 if (LValueToRValueConversion) {
9069 Result.setFrom(Info.Ctx, RVal);
9080 bool InvalidBaseOK) {
9084 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9087bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *
E) {
9095 E->refersToEnclosingVariableOrCapture()) {
9100 if (Info.checkingPotentialConstantExpression())
9103 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(
D)) {
9104 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9112 return Success(cast<ValueDecl>(
D));
9113 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
9114 return VisitVarDecl(
E, VD);
9116 return Visit(BD->getBinding());
9120bool LValueExprEvaluator::VisitVarDecl(
const Expr *
E,
const VarDecl *VD) {
9121 CallStackFrame *Frame =
nullptr;
9122 unsigned Version = 0;
9130 CallStackFrame *CurrFrame = Info.CurrentCall;
9131 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
9135 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9136 if (CurrFrame->Arguments) {
9137 VD = CurrFrame->Arguments.getOrigParam(PVD);
9139 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9140 Version = CurrFrame->Arguments.Version;
9144 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9151 Result.set({VD, Frame->Index, Version});
9157 if (!Info.getLangOpts().CPlusPlus11) {
9158 Info.CCEDiag(
E, diag::note_constexpr_ltor_non_integral, 1)
9160 Info.Note(VD->
getLocation(), diag::note_declared_at);
9169 Result.AllowConstexprUnknown =
true;
9176bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
9177 if (!IsConstantEvaluatedBuiltinCall(
E))
9178 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
9180 switch (
E->getBuiltinCallee()) {
9183 case Builtin::BIas_const:
9184 case Builtin::BIforward:
9185 case Builtin::BIforward_like:
9186 case Builtin::BImove:
9187 case Builtin::BImove_if_noexcept:
9188 if (cast<FunctionDecl>(
E->getCalleeDecl())->isConstexpr())
9189 return Visit(
E->getArg(0));
9193 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
9196bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9205 for (
const Expr *
E : CommaLHSs)
9214 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
9217 Value =
E->getOrCreateValue(
true);
9221 Value = &Info.CurrentCall->createTemporary(
9222 E, Inner->getType(),
9237 for (
unsigned I = Adjustments.size(); I != 0; ) {
9239 switch (Adjustments[I].Kind) {
9244 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9250 Type = Adjustments[I].Field->getType();
9255 Adjustments[I].Ptr.RHS))
9257 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9267 assert((!Info.getLangOpts().CPlusPlus ||
E->isFileScope()) &&
9268 "lvalue compound literal in c++?");
9272 if (
E->hasStaticStorage()) {
9273 Lit = &
E->getOrCreateStaticValue(Info.Ctx);
9280 assert(!Info.getLangOpts().CPlusPlus);
9281 Lit = &Info.CurrentCall->createTemporary(
E,
E->getInitializer()->
getType(),
9282 ScopeKind::Block, Result);
9294bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *
E) {
9297 if (!
E->isPotentiallyEvaluated()) {
9298 if (
E->isTypeOperand())
9303 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9304 Info.CCEDiag(
E, diag::note_constexpr_typeid_polymorphic)
9309 if (!Visit(
E->getExprOperand()))
9312 std::optional<DynamicType> DynType =
9318 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9324bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *
E) {
9328bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *
E) {
9330 if (
const VarDecl *VD = dyn_cast<VarDecl>(
E->getMemberDecl())) {
9331 VisitIgnoredBaseExpression(
E->getBase());
9332 return VisitVarDecl(
E, VD);
9336 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(
E->getMemberDecl())) {
9337 if (MD->isStatic()) {
9338 VisitIgnoredBaseExpression(
E->getBase());
9344 return LValueExprEvaluatorBaseTy::VisitMemberExpr(
E);
9347bool LValueExprEvaluator::VisitExtVectorElementExpr(
9352 if (!
Evaluate(Val, Info,
E->getBase())) {
9353 if (!Info.noteFailure())
9359 E->getEncodedElementAccess(Indices);
9361 if (Indices.size() > 1)
9365 Result.setFrom(Info.Ctx, Val);
9371 VT->getNumElements(), Indices[0]);
9386 if (!
Evaluate(Val, Info,
E->getBase())) {
9387 if (!Info.noteFailure())
9393 if (!Info.noteFailure())
9399 Result.setFrom(Info.Ctx, Val);
9401 VT->getNumElements(), Index.getExtValue());
9409 for (
const Expr *SubExpr : {
E->getLHS(),
E->getRHS()}) {
9410 if (SubExpr ==
E->getBase() ? !evaluatePointer(SubExpr, Result)
9412 if (!Info.noteFailure())
9422bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *
E) {
9423 bool Success = evaluatePointer(
E->getSubExpr(), Result);
9433 Info.noteUndefinedBehavior();
9436bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
9437 if (!Visit(
E->getSubExpr()))
9445bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
9447 "lvalue __imag__ on scalar?");
9448 if (!Visit(
E->getSubExpr()))
9454bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9455 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9466bool LValueExprEvaluator::VisitCompoundAssignOperator(
9468 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9476 if (!Info.noteFailure())
9492 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9499 if (!
Evaluate(NewVal, this->Info,
E->getRHS())) {
9500 if (!Info.noteFailure())
9505 if (!this->Visit(
E->getLHS()) || !
Success)
9508 if (Info.getLangOpts().CPlusPlus20 &&
9524 llvm::APInt &Result) {
9525 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9526 "Can't get the size of a non alloc_size function");
9527 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9529 std::optional<llvm::APInt> Size =
9530 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9534 Result = std::move(*Size);
9553 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9558 if (!
Init ||
Init->getType().isNull())
9562 if (!tryUnwrapAllocSizeCall(
E))
9567 Result.setInvalid(
E);
9570 Result.addUnsizedArray(Info,
E, Pointee);
9575class PointerExprEvaluator
9576 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9585 bool evaluateLValue(
const Expr *
E, LValue &Result) {
9589 bool evaluatePointer(
const Expr *
E, LValue &Result) {
9593 bool visitNonBuiltinCallExpr(
const CallExpr *
E);
9596 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9597 : ExprEvaluatorBaseTy(info), Result(Result),
9598 InvalidBaseOK(InvalidBaseOK) {}
9601 Result.setFrom(Info.Ctx,
V);
9604 bool ZeroInitialization(
const Expr *
E) {
9605 Result.setNull(Info.Ctx,
E->
getType());
9615 if (
E->isExpressibleAsConstantInitializer())
9617 if (Info.noteFailure())
9624 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
9626 if (!
E->getBlockDecl()->hasCaptures())
9631 auto DiagnoseInvalidUseOfThis = [&] {
9632 if (Info.getLangOpts().CPlusPlus11)
9633 Info.FFDiag(
E, diag::note_constexpr_this) <<
E->isImplicit();
9639 if (Info.checkingPotentialConstantExpression())
9642 bool IsExplicitLambda =
9644 if (!IsExplicitLambda) {
9645 if (!Info.CurrentCall->This) {
9646 DiagnoseInvalidUseOfThis();
9650 Result = *Info.CurrentCall->This;
9658 if (!Info.CurrentCall->LambdaThisCaptureField) {
9659 if (IsExplicitLambda && !Info.CurrentCall->This) {
9660 DiagnoseInvalidUseOfThis();
9667 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9669 Info,
E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9678 assert(!
E->isIntType() &&
"SourceLocExpr isn't a pointer type?");
9679 APValue LValResult =
E->EvaluateInContext(
9680 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9681 Result.setFrom(Info.Ctx, LValResult);
9686 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
9691 std::string ResultStr =
E->ComputeName(Info.Ctx);
9694 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9695 ResultStr.size() + 1);
9696 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9697 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9701 false, ArrayTy,
E->getLocation());
9703 evaluateLValue(SL, Result);
9704 Result.addArray(Info,
E, cast<ConstantArrayType>(ArrayTy));
9713 bool InvalidBaseOK) {
9716 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(
E);
9719bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
9720 if (
E->getOpcode() != BO_Add &&
9721 E->getOpcode() != BO_Sub)
9722 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
9724 const Expr *PExp =
E->getLHS();
9725 const Expr *IExp =
E->getRHS();
9727 std::swap(PExp, IExp);
9729 bool EvalPtrOK = evaluatePointer(PExp, Result);
9730 if (!EvalPtrOK && !Info.noteFailure())
9733 llvm::APSInt Offset;
9737 if (
E->getOpcode() == BO_Sub)
9744bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
9745 return evaluateLValue(
E->getSubExpr(), Result);
9753 if (!FnII || !FnII->
isStr(
"current"))
9756 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9764bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
9765 const Expr *SubExpr =
E->getSubExpr();
9767 switch (
E->getCastKind()) {
9771 case CK_CPointerToObjCPointerCast:
9772 case CK_BlockPointerToObjCPointerCast:
9773 case CK_AnyPointerToBlockPointerCast:
9774 case CK_AddressSpaceConversion:
9775 if (!Visit(SubExpr))
9781 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9782 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9783 << Info.Ctx.getLangOpts().CPlusPlus;
9784 Result.Designator.setInvalid();
9792 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9794 bool VoidPtrCastMaybeOK =
9797 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9806 if (VoidPtrCastMaybeOK &&
9807 (Info.getStdAllocatorCaller(
"allocate") ||
9809 Info.getLangOpts().CPlusPlus26)) {
9813 Info.getLangOpts().CPlusPlus) {
9815 CCEDiag(
E, diag::note_constexpr_invalid_void_star_cast)
9816 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9817 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9820 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9821 << diag::ConstexprInvalidCastKind::CastFrom
9824 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9825 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9826 << Info.Ctx.getLangOpts().CPlusPlus;
9827 Result.Designator.setInvalid();
9830 if (
E->getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9831 ZeroInitialization(
E);
9834 case CK_DerivedToBase:
9835 case CK_UncheckedDerivedToBase:
9836 if (!evaluatePointer(
E->getSubExpr(), Result))
9838 if (!Result.Base && Result.Offset.isZero())
9847 case CK_BaseToDerived:
9848 if (!Visit(
E->getSubExpr()))
9850 if (!Result.Base && Result.Offset.isZero())
9855 if (!Visit(
E->getSubExpr()))
9859 case CK_NullToPointer:
9860 VisitIgnoredValue(
E->getSubExpr());
9861 return ZeroInitialization(
E);
9863 case CK_IntegralToPointer: {
9864 CCEDiag(
E, diag::note_constexpr_invalid_cast)
9865 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9866 << Info.Ctx.getLangOpts().CPlusPlus;
9872 if (
Value.isInt()) {
9874 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9875 if (N == Info.Ctx.getTargetNullPointerValue(
E->
getType())) {
9876 Result.setNull(Info.Ctx,
E->
getType());
9878 Result.Base = (
Expr *)
nullptr;
9879 Result.InvalidBase =
false;
9881 Result.Designator.setInvalid();
9882 Result.IsNullPtr =
false;
9890 if (!
Value.isLValue())
9894 Result.setFrom(Info.Ctx,
Value);
9899 case CK_ArrayToPointerDecay: {
9901 if (!evaluateLValue(SubExpr, Result))
9905 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9910 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9911 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9912 Result.addArray(Info,
E, CAT);
9914 Result.addUnsizedArray(Info,
E, AT->getElementType());
9918 case CK_FunctionToPointerDecay:
9919 return evaluateLValue(SubExpr, Result);
9921 case CK_LValueToRValue: {
9923 if (!evaluateLValue(
E->getSubExpr(), LVal))
9930 return InvalidBaseOK &&
9936 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
9944 T =
T.getNonReferenceType();
9946 if (
T.getQualifiers().hasUnaligned())
9949 const bool AlignOfReturnsPreferred =
9950 Ctx.
getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9955 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9958 else if (ExprKind == UETT_AlignOf)
9961 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9978 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E))
9987 return Info.Ctx.getDeclAlign(VD);
9988 if (
const auto *
E =
Value.Base.dyn_cast<
const Expr *>())
9996 EvalInfo &Info,
APSInt &Alignment) {
9999 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10000 Info.FFDiag(
E, diag::note_constexpr_invalid_alignment) << Alignment;
10003 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10004 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10005 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10006 Info.FFDiag(
E, diag::note_constexpr_alignment_too_big)
10007 << MaxValue << ForType << Alignment;
10013 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10014 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10015 "Alignment should not be changed by ext/trunc");
10016 Alignment = ExtAlignment;
10017 assert(Alignment.getBitWidth() == SrcWidth);
10022bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *
E) {
10023 if (ExprEvaluatorBaseTy::VisitCallExpr(
E))
10026 if (!(InvalidBaseOK &&
E->getCalleeAllocSizeAttr()))
10029 Result.setInvalid(
E);
10031 Result.addUnsizedArray(Info,
E, PointeeTy);
10035bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
10036 if (!IsConstantEvaluatedBuiltinCall(
E))
10037 return visitNonBuiltinCallExpr(
E);
10038 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
10047bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
10048 unsigned BuiltinOp) {
10052 switch (BuiltinOp) {
10053 case Builtin::BIaddressof:
10054 case Builtin::BI__addressof:
10055 case Builtin::BI__builtin_addressof:
10056 return evaluateLValue(
E->getArg(0), Result);
10057 case Builtin::BI__builtin_assume_aligned: {
10061 if (!evaluatePointer(
E->getArg(0), Result))
10064 LValue OffsetResult(Result);
10071 if (
E->getNumArgs() > 2) {
10076 int64_t AdditionalOffset = -Offset.getZExtValue();
10081 if (OffsetResult.Base) {
10084 if (BaseAlignment < Align) {
10085 Result.Designator.setInvalid();
10086 CCEDiag(
E->getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10093 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10094 Result.Designator.setInvalid();
10097 ? CCEDiag(
E->getArg(0),
10098 diag::note_constexpr_baa_insufficient_alignment)
10100 : CCEDiag(
E->getArg(0),
10101 diag::note_constexpr_baa_value_insufficient_alignment))
10102 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10108 case Builtin::BI__builtin_align_up:
10109 case Builtin::BI__builtin_align_down: {
10110 if (!evaluatePointer(
E->getArg(0), Result))
10129 assert(Alignment.getBitWidth() <= 64 &&
10130 "Cannot handle > 64-bit address-space");
10131 uint64_t Alignment64 = Alignment.getZExtValue();
10133 BuiltinOp == Builtin::BI__builtin_align_down
10134 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
10135 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
10136 Result.adjustOffset(NewOffset - Result.Offset);
10141 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_adjust)
10145 case Builtin::BI__builtin_operator_new:
10147 case Builtin::BI__builtin_launder:
10148 return evaluatePointer(
E->getArg(0), Result);
10149 case Builtin::BIstrchr:
10150 case Builtin::BIwcschr:
10151 case Builtin::BImemchr:
10152 case Builtin::BIwmemchr:
10153 if (Info.getLangOpts().CPlusPlus11)
10154 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
10156 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10158 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
10160 case Builtin::BI__builtin_strchr:
10161 case Builtin::BI__builtin_wcschr:
10162 case Builtin::BI__builtin_memchr:
10163 case Builtin::BI__builtin_char_memchr:
10164 case Builtin::BI__builtin_wmemchr: {
10165 if (!Visit(
E->getArg(0)))
10171 if (BuiltinOp != Builtin::BIstrchr &&
10172 BuiltinOp != Builtin::BIwcschr &&
10173 BuiltinOp != Builtin::BI__builtin_strchr &&
10174 BuiltinOp != Builtin::BI__builtin_wcschr) {
10178 MaxLength = N.getZExtValue();
10181 if (MaxLength == 0u)
10182 return ZeroInitialization(
E);
10183 if (!Result.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
10184 Result.Designator.Invalid)
10186 QualType CharTy = Result.Designator.getType(Info.Ctx);
10187 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10188 BuiltinOp == Builtin::BI__builtin_memchr;
10189 assert(IsRawByte ||
10190 Info.Ctx.hasSameUnqualifiedType(
10194 Info.FFDiag(
E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10200 Info.FFDiag(
E, diag::note_constexpr_memchr_unsupported)
10201 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10207 bool StopAtNull =
false;
10208 switch (BuiltinOp) {
10209 case Builtin::BIstrchr:
10210 case Builtin::BI__builtin_strchr:
10217 return ZeroInitialization(
E);
10220 case Builtin::BImemchr:
10221 case Builtin::BI__builtin_memchr:
10222 case Builtin::BI__builtin_char_memchr:
10226 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10229 case Builtin::BIwcschr:
10230 case Builtin::BI__builtin_wcschr:
10233 case Builtin::BIwmemchr:
10234 case Builtin::BI__builtin_wmemchr:
10236 DesiredVal = Desired.getZExtValue();
10240 for (; MaxLength; --MaxLength) {
10245 if (Char.
getInt().getZExtValue() == DesiredVal)
10247 if (StopAtNull && !Char.
getInt())
10253 return ZeroInitialization(
E);
10256 case Builtin::BImemcpy:
10257 case Builtin::BImemmove:
10258 case Builtin::BIwmemcpy:
10259 case Builtin::BIwmemmove:
10260 if (Info.getLangOpts().CPlusPlus11)
10261 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
10263 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10265 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
10267 case Builtin::BI__builtin_memcpy:
10268 case Builtin::BI__builtin_memmove:
10269 case Builtin::BI__builtin_wmemcpy:
10270 case Builtin::BI__builtin_wmemmove: {
10271 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10272 BuiltinOp == Builtin::BIwmemmove ||
10273 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10274 BuiltinOp == Builtin::BI__builtin_wmemmove;
10275 bool Move = BuiltinOp == Builtin::BImemmove ||
10276 BuiltinOp == Builtin::BIwmemmove ||
10277 BuiltinOp == Builtin::BI__builtin_memmove ||
10278 BuiltinOp == Builtin::BI__builtin_wmemmove;
10281 if (!Visit(
E->getArg(0)))
10283 LValue Dest = Result;
10292 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10302 if (!Src.Base || !Dest.Base) {
10304 (!Src.Base ? Src : Dest).moveInto(Val);
10305 Info.FFDiag(
E, diag::note_constexpr_memcpy_null)
10306 <<
Move << WChar << !!Src.Base
10310 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10316 QualType T = Dest.Designator.getType(Info.Ctx);
10317 QualType SrcT = Src.Designator.getType(Info.Ctx);
10318 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
10320 Info.FFDiag(
E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
10324 Info.FFDiag(
E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
10327 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
10328 Info.FFDiag(
E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
10333 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
10338 llvm::APInt OrigN = N;
10339 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10341 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10351 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10352 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10353 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10354 Info.FFDiag(
E, diag::note_constexpr_memcpy_unsupported)
10355 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
10359 uint64_t NElems = N.getZExtValue();
10365 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10366 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10367 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10370 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10378 }
else if (!Move && SrcOffset >= DestOffset &&
10379 SrcOffset - DestOffset < NBytes) {
10381 Info.FFDiag(
E, diag::note_constexpr_memcpy_overlap) << WChar;
10416bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *
E) {
10417 if (!Info.getLangOpts().CPlusPlus20)
10418 Info.CCEDiag(
E, diag::note_constexpr_new);
10421 if (Info.SpeculativeEvaluationDepth)
10425 QualType AllocType =
E->getAllocatedType();
10428 bool IsNothrow =
false;
10429 bool IsPlacement =
false;
10431 if (
E->getNumPlacementArgs() == 1 &&
10447 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10448 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10449 (Info.CurrentCall->CanEvalMSConstexpr &&
10450 OperatorNew->hasAttr<MSConstexprAttr>())) {
10453 if (Result.Designator.Invalid)
10455 TargetType =
E->getPlacementArg(0)->
getType();
10456 IsPlacement =
true;
10458 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10462 }
else if (
E->getNumPlacementArgs()) {
10463 Info.FFDiag(
E, diag::note_constexpr_new_placement)
10466 }
else if (!OperatorNew
10467 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10468 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
10469 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
10473 const Expr *
Init =
E->getInitializer();
10476 bool ValueInit =
false;
10478 if (std::optional<const Expr *> ArraySize =
E->getArraySize()) {
10479 const Expr *Stripped = *ArraySize;
10480 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10481 Stripped = ICE->getSubExpr())
10482 if (ICE->getCastKind() != CK_NoOp &&
10483 ICE->getCastKind() != CK_IntegralCast)
10496 return ZeroInitialization(
E);
10498 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10499 <<
ArrayBound << (*ArraySize)->getSourceRange();
10505 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10510 return ZeroInitialization(
E);
10519 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
10520 isa<ImplicitValueInitExpr>(
Init)) {
10522 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10523 ResizedArrayCCE = CCE;
10525 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10526 assert(CAT &&
"unexpected type for array initializer");
10530 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10531 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10532 if (InitBound.ugt(AllocBound)) {
10534 return ZeroInitialization(
E);
10536 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10537 <<
toString(AllocBound, 10,
false)
10539 << (*ArraySize)->getSourceRange();
10545 if (InitBound != AllocBound)
10546 ResizedArrayILE = cast<InitListExpr>(
Init);
10549 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10550 ArraySizeModifier::Normal, 0);
10553 "array allocation with non-array new");
10559 struct FindObjectHandler {
10566 typedef bool result_type;
10567 bool failed() {
return false; }
10570 Info.FFDiag(
E, diag::note_constexpr_modify_const_type) << QT;
10576 if (!checkConst(SubobjType))
10580 unsigned SubobjectSize = 1;
10581 unsigned AllocSize = 1;
10582 if (
auto *CAT = dyn_cast<ConstantArrayType>(AllocType))
10584 if (
auto *CAT = dyn_cast<ConstantArrayType>(SubobjType))
10586 if (SubobjectSize < AllocSize ||
10587 !Info.Ctx.hasSimilarType(Info.Ctx.getBaseElementType(SubobjType),
10588 Info.Ctx.getBaseElementType(AllocType))) {
10589 Info.FFDiag(
E, diag::note_constexpr_placement_new_wrong_type)
10590 << SubobjType << AllocType;
10597 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10601 Info.FFDiag(
E, diag::note_constexpr_construct_complex_elem);
10604 } Handler = {Info,
E, AllocType, AK,
nullptr};
10607 if (!Obj || !
findSubobject(Info,
E, Obj, Result.Designator, Handler))
10610 Val = Handler.Value;
10619 Val = Info.createHeapAlloc(
E, AllocType, Result);
10628 }
else if (ResizedArrayILE) {
10632 }
else if (ResizedArrayCCE) {
10646 Result.addArray(Info,
E, cast<ConstantArrayType>(AT));
10655class MemberPointerExprEvaluator
10656 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10660 Result = MemberPtr(
D);
10665 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10666 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10672 bool ZeroInitialization(
const Expr *
E) {
10685 return MemberPointerExprEvaluator(Info, Result).Visit(
E);
10688bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10689 switch (
E->getCastKind()) {
10691 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10693 case CK_NullToMemberPointer:
10694 VisitIgnoredValue(
E->getSubExpr());
10695 return ZeroInitialization(
E);
10697 case CK_BaseToDerivedMemberPointer: {
10698 if (!Visit(
E->getSubExpr()))
10700 if (
E->path_empty())
10705 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10706 for (ReverseIter PathI(
E->path_end() - 1), PathE(
E->path_begin());
10707 PathI != PathE; ++PathI) {
10708 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10709 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10710 if (!Result.castToDerived(Derived))
10713 if (!Result.castToDerived(
E->
getType()
10720 case CK_DerivedToBaseMemberPointer:
10721 if (!Visit(
E->getSubExpr()))
10724 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10725 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10727 if (!Result.castToBase(
Base))
10734bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *
E) {
10737 return Success(cast<DeclRefExpr>(
E->getSubExpr())->getDecl());
10745 class RecordExprEvaluator
10746 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10747 const LValue &
This;
10751 RecordExprEvaluator(EvalInfo &info,
const LValue &
This,
APValue &Result)
10752 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10758 bool ZeroInitialization(
const Expr *
E) {
10759 return ZeroInitialization(
E,
E->
getType());
10763 bool VisitCallExpr(
const CallExpr *
E) {
10764 return handleCallExpr(
E, Result, &
This);
10769 return VisitCXXConstructExpr(
E,
E->
getType());
10777 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10792 assert(!RD->
isUnion() &&
"Expected non-union class type");
10801 unsigned Index = 0;
10803 End = CD->
bases_end(); I != End; ++I, ++Index) {
10805 LValue Subobject =
This;
10809 Result.getStructBase(Index)))
10814 for (
const auto *I : RD->
fields()) {
10816 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10819 LValue Subobject =
This;
10825 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10832bool RecordExprEvaluator::ZeroInitialization(
const Expr *
E,
QualType T) {
10839 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10846 LValue Subobject =
This;
10851 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10854 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10855 Info.FFDiag(
E, diag::note_constexpr_virtual_base) << RD;
10862bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
10863 switch (
E->getCastKind()) {
10865 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
10867 case CK_ConstructorConversion:
10868 return Visit(
E->getSubExpr());
10870 case CK_DerivedToBase:
10871 case CK_UncheckedDerivedToBase: {
10873 if (!
Evaluate(DerivedObject, Info,
E->getSubExpr()))
10876 return Error(
E->getSubExpr());
10882 PathE =
E->path_end(); PathI != PathE; ++PathI) {
10883 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10894bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
10895 if (
E->isTransparent())
10896 return Visit(
E->getInit(0));
10897 return VisitCXXParenListOrInitListExpr(
E,
E->inits());
10900bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10905 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10907 EvalInfo::EvaluatingConstructorRAII EvalObj(
10909 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10910 CXXRD && CXXRD->getNumBases());
10914 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10915 Field = ILE->getInitializedFieldInUnion();
10916 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10917 Field = PLIE->getInitializedFieldInUnion();
10920 "Expression is neither an init list nor a C++ paren list");
10933 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10935 LValue Subobject =
This;
10940 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &
This,
10941 isa<CXXDefaultInitExpr>(InitExpr));
10943 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10944 if (
Field->isBitField())
10953 if (!Result.hasValue())
10956 unsigned ElementNo = 0;
10960 if (CXXRD && CXXRD->getNumBases()) {
10961 for (
const auto &
Base : CXXRD->bases()) {
10962 assert(ElementNo < Args.size() &&
"missing init for base class");
10963 const Expr *
Init = Args[ElementNo];
10965 LValue Subobject =
This;
10969 APValue &FieldVal = Result.getStructBase(ElementNo);
10971 if (!Info.noteFailure())
10978 EvalObj.finishedConstructingBases();
10982 for (
const auto *Field : RD->
fields()) {
10985 if (
Field->isUnnamedBitField())
10988 LValue Subobject =
This;
10990 bool HaveInit = ElementNo < Args.size();
10995 Subobject, Field, &Layout))
11001 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11003 if (
Field->getType()->isIncompleteArrayType()) {
11004 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11008 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11015 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &
This,
11016 isa<CXXDefaultInitExpr>(
Init));
11018 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
11019 if (
Field->getType()->isReferenceType()) {
11023 if (!Info.noteFailure())
11028 (
Field->isBitField() &&
11030 if (!Info.noteFailure())
11036 EvalObj.finishedConstructingFields();
11048 bool ZeroInit =
E->requiresZeroInitialization();
11051 return ZeroInitialization(
E,
T);
11063 if (
E->isElidable() && !ZeroInit) {
11069 const Expr *SrcObj =
E->getArg(0);
11071 assert(Info.Ctx.hasSameUnqualifiedType(
E->
getType(), SrcObj->
getType()));
11073 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11074 return Visit(ME->getSubExpr());
11077 if (ZeroInit && !ZeroInitialization(
E,
T))
11080 auto Args =
ArrayRef(
E->getArgs(),
E->getNumArgs());
11086bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11088 if (!Info.CurrentCall) {
11089 assert(Info.checkingPotentialConstantExpression());
11108bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11111 Info.Ctx.getAsConstantArrayType(
E->getSubExpr()->
getType());
11117 assert(
ArrayType &&
"unexpected type for array initializer");
11124 Array.moveInto(Result.getStructField(0));
11128 assert(Field !=
Record->field_end() &&
11129 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11131 "Expected std::initializer_list first field to be const E *");
11133 assert(Field !=
Record->field_end() &&
11134 "Expected std::initializer_list to have two fields");
11136 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11141 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11143 "Expected std::initializer_list second field to be const E *");
11148 Array.moveInto(Result.getStructField(1));
11151 assert(++Field ==
Record->field_end() &&
11152 "Expected std::initializer_list to only have two fields");
11157bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *
E) {
11162 const size_t NumFields =
11165 assert(NumFields == (
size_t)std::distance(
E->capture_init_begin(),
11166 E->capture_init_end()) &&
11167 "The number of lambda capture initializers should equal the number of "
11168 "fields within the closure type");
11173 auto *CaptureInitIt =
E->capture_init_begin();
11175 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11176 for (
const auto *Field : ClosureClass->
fields()) {
11177 assert(CaptureInitIt !=
E->capture_init_end());
11179 Expr *
const CurFieldInit = *CaptureInitIt++;
11186 LValue Subobject =
This;
11191 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
11193 if (!Info.keepEvaluatingAfterFailure())
11202 APValue &Result, EvalInfo &Info) {
11205 "can't evaluate expression as a record rvalue");
11206 return RecordExprEvaluator(Info,
This, Result).Visit(
E);
11217class TemporaryExprEvaluator
11218 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11220 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
11221 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
11224 bool VisitConstructExpr(
const Expr *
E) {
11226 E,
E->
getType(), ScopeKind::FullExpression, Result);
11230 bool VisitCastExpr(
const CastExpr *
E) {
11231 switch (
E->getCastKind()) {
11233 return LValueExprEvaluatorBaseTy::VisitCastExpr(
E);
11235 case CK_ConstructorConversion:
11236 return VisitConstructExpr(
E->getSubExpr());
11240 return VisitConstructExpr(
E);
11243 return VisitConstructExpr(
E);
11245 bool VisitCallExpr(
const CallExpr *
E) {
11246 return VisitConstructExpr(
E);
11249 return VisitConstructExpr(
E);
11252 return VisitConstructExpr(
E);
11261 return TemporaryExprEvaluator(Info, Result).Visit(
E);
11269 class VectorExprEvaluator
11270 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11274 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
11275 : ExprEvaluatorBaseTy(info), Result(Result) {}
11284 assert(
V.isVector());
11288 bool ZeroInitialization(
const Expr *
E);
11291 {
return Visit(
E->getSubExpr()); }
11308 "not a vector prvalue");
11309 return VectorExprEvaluator(Info, Result).Visit(
E);
11313 assert(Val.
isVector() &&
"expected vector APValue");
11317 llvm::APInt Result(NumElts, 0);
11319 for (
unsigned I = 0; I < NumElts; ++I) {
11321 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11323 if (Elt.
getInt().getBoolValue())
11330bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
11334 const Expr *SE =
E->getSubExpr();
11337 switch (
E->getCastKind()) {
11338 case CK_VectorSplat: {
11344 Val =
APValue(std::move(IntResult));
11349 Val =
APValue(std::move(FloatResult));
11366 Info.FFDiag(
E, diag::note_constexpr_invalid_cast)
11367 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11368 << Info.Ctx.getLangOpts().CPlusPlus;
11372 if (!handleRValueToRValueBitCast(Info, Result, SVal,
E))
11377 case CK_HLSLVectorTruncation: {
11382 for (
unsigned I = 0; I < NElts; I++)
11387 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
11392VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
11394 unsigned NumInits =
E->getNumInits();
11409 unsigned CountInits = 0, CountElts = 0;
11410 while (CountElts < NumElements) {
11412 if (CountInits < NumInits
11418 for (
unsigned j = 0; j < vlen; j++)
11422 llvm::APSInt sInt(32);
11423 if (CountInits < NumInits) {
11427 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11428 Elements.push_back(
APValue(sInt));
11431 llvm::APFloat f(0.0);
11432 if (CountInits < NumInits) {
11436 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11437 Elements.push_back(
APValue(f));
11446VectorExprEvaluator::ZeroInitialization(
const Expr *
E) {
11450 if (EltTy->isIntegerType())
11451 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
11454 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
11460bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
11461 VisitIgnoredValue(
E->getSubExpr());
11462 return ZeroInitialization(
E);
11465bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
11467 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
11468 "Operation not supported on vector types");
11470 if (Op == BO_Comma)
11471 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
11473 Expr *LHS =
E->getLHS();
11474 Expr *RHS =
E->getRHS();
11477 "Must both be vector types");
11484 "All operands must be the same size.");
11488 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
11489 if (!LHSOK && !Info.noteFailure())
11491 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
11513 "Vector can only be int or float type");
11521 "Vector operator ~ can only be int");
11522 Elt.
getInt().flipAllBits();
11532 "Vector can only be int or float type");
11538 EltResult.setAllBits();
11540 EltResult.clearAllBits();
11546 return std::nullopt;
11550bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
11551 Expr *SubExpr =
E->getSubExpr();
11556 const QualType ResultEltTy = VD->getElementType();
11560 if (!
Evaluate(SubExprValue, Info, SubExpr))
11573 "Vector length doesn't match type?");
11576 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
11578 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
11581 ResultElements.push_back(*Elt);
11583 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11592 Result =
APValue(APFloat(0.0));
11594 DestTy, Result.getFloat());
11605 Result.getFloat());
11610 DestTy, Result.getInt());
11614 Info.FFDiag(
E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11615 << SourceTy << DestTy;
11619bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
11620 if (!IsConstantEvaluatedBuiltinCall(
E))
11621 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
11623 switch (
E->getBuiltinCallee()) {
11626 case Builtin::BI__builtin_elementwise_popcount:
11627 case Builtin::BI__builtin_elementwise_bitreverse: {
11635 ResultElements.reserve(SourceLen);
11637 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11639 switch (
E->getBuiltinCallee()) {
11640 case Builtin::BI__builtin_elementwise_popcount:
11641 ResultElements.push_back(
APValue(
11642 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
11645 case Builtin::BI__builtin_elementwise_bitreverse:
11646 ResultElements.push_back(
11653 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11655 case Builtin::BI__builtin_elementwise_abs: {
11663 ResultElements.reserve(SourceLen);
11665 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11670 CurrentEle.getInt().
abs(),
11671 DestEltTy->isUnsignedIntegerOrEnumerationType()));
11672 ResultElements.push_back(Val);
11675 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11678 case Builtin::BI__builtin_elementwise_add_sat:
11679 case Builtin::BI__builtin_elementwise_sub_sat:
11680 case clang::X86::BI__builtin_ia32_pmulhuw128:
11681 case clang::X86::BI__builtin_ia32_pmulhuw256:
11682 case clang::X86::BI__builtin_ia32_pmulhuw512:
11683 case clang::X86::BI__builtin_ia32_pmulhw128:
11684 case clang::X86::BI__builtin_ia32_pmulhw256:
11685 case clang::X86::BI__builtin_ia32_pmulhw512:
11686 case clang::X86::BI__builtin_ia32_psllv2di:
11687 case clang::X86::BI__builtin_ia32_psllv4di:
11688 case clang::X86::BI__builtin_ia32_psllv4si:
11689 case clang::X86::BI__builtin_ia32_psllv8si:
11690 case clang::X86::BI__builtin_ia32_psrav4si:
11691 case clang::X86::BI__builtin_ia32_psrav8si:
11692 case clang::X86::BI__builtin_ia32_psrlv2di:
11693 case clang::X86::BI__builtin_ia32_psrlv4di:
11694 case clang::X86::BI__builtin_ia32_psrlv4si:
11695 case clang::X86::BI__builtin_ia32_psrlv8si:
11697 case clang::X86::BI__builtin_ia32_psllwi128:
11698 case clang::X86::BI__builtin_ia32_pslldi128:
11699 case clang::X86::BI__builtin_ia32_psllqi128:
11700 case clang::X86::BI__builtin_ia32_psllwi256:
11701 case clang::X86::BI__builtin_ia32_pslldi256:
11702 case clang::X86::BI__builtin_ia32_psllqi256:
11703 case clang::X86::BI__builtin_ia32_psllwi512:
11704 case clang::X86::BI__builtin_ia32_pslldi512:
11705 case clang::X86::BI__builtin_ia32_psllqi512:
11707 case clang::X86::BI__builtin_ia32_psrlwi128:
11708 case clang::X86::BI__builtin_ia32_psrldi128:
11709 case clang::X86::BI__builtin_ia32_psrlqi128:
11710 case clang::X86::BI__builtin_ia32_psrlwi256:
11711 case clang::X86::BI__builtin_ia32_psrldi256:
11712 case clang::X86::BI__builtin_ia32_psrlqi256:
11713 case clang::X86::BI__builtin_ia32_psrlwi512:
11714 case clang::X86::BI__builtin_ia32_psrldi512:
11715 case clang::X86::BI__builtin_ia32_psrlqi512:
11717 case clang::X86::BI__builtin_ia32_psrawi128:
11718 case clang::X86::BI__builtin_ia32_psradi128:
11719 case clang::X86::BI__builtin_ia32_psraqi128:
11720 case clang::X86::BI__builtin_ia32_psrawi256:
11721 case clang::X86::BI__builtin_ia32_psradi256:
11722 case clang::X86::BI__builtin_ia32_psraqi256:
11723 case clang::X86::BI__builtin_ia32_psrawi512:
11724 case clang::X86::BI__builtin_ia32_psradi512:
11725 case clang::X86::BI__builtin_ia32_psraqi512: {
11727 APValue SourceLHS, SourceRHS;
11736 ResultElements.reserve(SourceLen);
11738 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11741 if (SourceRHS.
isInt()) {
11742 const unsigned LaneBitWidth = LHS.getBitWidth();
11743 const unsigned ShiftAmount = SourceRHS.
getInt().getZExtValue();
11745 switch (
E->getBuiltinCallee()) {
11746 case clang::X86::BI__builtin_ia32_psllwi128:
11747 case clang::X86::BI__builtin_ia32_psllwi256:
11748 case clang::X86::BI__builtin_ia32_psllwi512:
11749 case clang::X86::BI__builtin_ia32_pslldi128:
11750 case clang::X86::BI__builtin_ia32_pslldi256:
11751 case clang::X86::BI__builtin_ia32_pslldi512:
11752 case clang::X86::BI__builtin_ia32_psllqi128:
11753 case clang::X86::BI__builtin_ia32_psllqi256:
11754 case clang::X86::BI__builtin_ia32_psllqi512:
11755 if (ShiftAmount >= LaneBitWidth) {
11756 ResultElements.push_back(
11757 APValue(
APSInt(APInt::getZero(LaneBitWidth), DestUnsigned)));
11759 ResultElements.push_back(
11763 case clang::X86::BI__builtin_ia32_psrlwi128:
11764 case clang::X86::BI__builtin_ia32_psrlwi256:
11765 case clang::X86::BI__builtin_ia32_psrlwi512:
11766 case clang::X86::BI__builtin_ia32_psrldi128:
11767 case clang::X86::BI__builtin_ia32_psrldi256:
11768 case clang::X86::BI__builtin_ia32_psrldi512:
11769 case clang::X86::BI__builtin_ia32_psrlqi128:
11770 case clang::X86::BI__builtin_ia32_psrlqi256:
11771 case clang::X86::BI__builtin_ia32_psrlqi512:
11772 if (ShiftAmount >= LaneBitWidth) {
11773 ResultElements.push_back(
11774 APValue(
APSInt(APInt::getZero(LaneBitWidth), DestUnsigned)));
11776 ResultElements.push_back(
11780 case clang::X86::BI__builtin_ia32_psrawi128:
11781 case clang::X86::BI__builtin_ia32_psrawi256:
11782 case clang::X86::BI__builtin_ia32_psrawi512:
11783 case clang::X86::BI__builtin_ia32_psradi128:
11784 case clang::X86::BI__builtin_ia32_psradi256:
11785 case clang::X86::BI__builtin_ia32_psradi512:
11786 case clang::X86::BI__builtin_ia32_psraqi128:
11787 case clang::X86::BI__builtin_ia32_psraqi256:
11788 case clang::X86::BI__builtin_ia32_psraqi512:
11789 ResultElements.push_back(
11790 APValue(
APSInt(LHS.ashr(std::min(ShiftAmount, LaneBitWidth - 1)),
11794 llvm_unreachable(
"Unexpected builtin callee");
11799 switch (
E->getBuiltinCallee()) {
11800 case Builtin::BI__builtin_elementwise_add_sat:
11801 ResultElements.push_back(
APValue(
11802 APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS),
11805 case Builtin::BI__builtin_elementwise_sub_sat:
11806 ResultElements.push_back(
APValue(
11807 APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS),
11810 case clang::X86::BI__builtin_ia32_pmulhuw128:
11811 case clang::X86::BI__builtin_ia32_pmulhuw256:
11812 case clang::X86::BI__builtin_ia32_pmulhuw512:
11813 ResultElements.push_back(
APValue(
APSInt(llvm::APIntOps::mulhu(LHS, RHS),
11816 case clang::X86::BI__builtin_ia32_pmulhw128:
11817 case clang::X86::BI__builtin_ia32_pmulhw256:
11818 case clang::X86::BI__builtin_ia32_pmulhw512:
11819 ResultElements.push_back(
APValue(
APSInt(llvm::APIntOps::mulhs(LHS, RHS),
11822 case clang::X86::BI__builtin_ia32_psllv2di:
11823 case clang::X86::BI__builtin_ia32_psllv4di:
11824 case clang::X86::BI__builtin_ia32_psllv4si:
11825 case clang::X86::BI__builtin_ia32_psllv8si:
11826 if (RHS.uge(RHS.getBitWidth())) {
11827 ResultElements.push_back(
11828 APValue(
APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
11831 ResultElements.push_back(
11832 APValue(
APSInt(LHS.shl(RHS.getZExtValue()), DestUnsigned)));
11834 case clang::X86::BI__builtin_ia32_psrav4si:
11835 case clang::X86::BI__builtin_ia32_psrav8si:
11836 if (RHS.uge(RHS.getBitWidth())) {
11837 ResultElements.push_back(
11838 APValue(
APSInt(LHS.ashr(RHS.getBitWidth() - 1), DestUnsigned)));
11841 ResultElements.push_back(
11842 APValue(
APSInt(LHS.ashr(RHS.getZExtValue()), DestUnsigned)));
11844 case clang::X86::BI__builtin_ia32_psrlv2di:
11845 case clang::X86::BI__builtin_ia32_psrlv4di:
11846 case clang::X86::BI__builtin_ia32_psrlv4si:
11847 case clang::X86::BI__builtin_ia32_psrlv8si:
11848 if (RHS.uge(RHS.getBitWidth())) {
11849 ResultElements.push_back(
11850 APValue(
APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
11853 ResultElements.push_back(
11854 APValue(
APSInt(LHS.lshr(RHS.getZExtValue()), DestUnsigned)));
11859 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11861 case clang::X86::BI__builtin_ia32_pmuldq128:
11862 case clang::X86::BI__builtin_ia32_pmuldq256:
11863 case clang::X86::BI__builtin_ia32_pmuldq512:
11864 case clang::X86::BI__builtin_ia32_pmuludq128:
11865 case clang::X86::BI__builtin_ia32_pmuludq256:
11866 case clang::X86::BI__builtin_ia32_pmuludq512: {
11867 APValue SourceLHS, SourceRHS;
11874 ResultElements.reserve(SourceLen / 2);
11876 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
11880 switch (
E->getBuiltinCallee()) {
11881 case clang::X86::BI__builtin_ia32_pmuludq128:
11882 case clang::X86::BI__builtin_ia32_pmuludq256:
11883 case clang::X86::BI__builtin_ia32_pmuludq512:
11884 ResultElements.push_back(
11885 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
11887 case clang::X86::BI__builtin_ia32_pmuldq128:
11888 case clang::X86::BI__builtin_ia32_pmuldq256:
11889 case clang::X86::BI__builtin_ia32_pmuldq512:
11890 ResultElements.push_back(
11891 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
11896 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11898 case clang::X86::BI__builtin_ia32_vprotbi:
11899 case clang::X86::BI__builtin_ia32_vprotdi:
11900 case clang::X86::BI__builtin_ia32_vprotqi:
11901 case clang::X86::BI__builtin_ia32_vprotwi:
11902 case clang::X86::BI__builtin_ia32_prold128:
11903 case clang::X86::BI__builtin_ia32_prold256:
11904 case clang::X86::BI__builtin_ia32_prold512:
11905 case clang::X86::BI__builtin_ia32_prolq128:
11906 case clang::X86::BI__builtin_ia32_prolq256:
11907 case clang::X86::BI__builtin_ia32_prolq512: {
11908 APValue SourceLHS, SourceRHS;
11917 ResultElements.reserve(SourceLen);
11921 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11923 ResultElements.push_back(
APValue(
APSInt(LHS.rotl(RHS), DestUnsigned)));
11926 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11928 case clang::X86::BI__builtin_ia32_prord128:
11929 case clang::X86::BI__builtin_ia32_prord256:
11930 case clang::X86::BI__builtin_ia32_prord512:
11931 case clang::X86::BI__builtin_ia32_prorq128:
11932 case clang::X86::BI__builtin_ia32_prorq256:
11933 case clang::X86::BI__builtin_ia32_prorq512: {
11934 APValue SourceLHS, SourceRHS;
11943 ResultElements.reserve(SourceLen);
11947 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11949 ResultElements.push_back(
APValue(
APSInt(LHS.rotr(RHS), DestUnsigned)));
11952 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11954 case Builtin::BI__builtin_elementwise_max:
11955 case Builtin::BI__builtin_elementwise_min: {
11956 APValue SourceLHS, SourceRHS;
11968 ResultElements.reserve(SourceLen);
11970 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11973 switch (
E->getBuiltinCallee()) {
11974 case Builtin::BI__builtin_elementwise_max:
11975 ResultElements.push_back(
11979 case Builtin::BI__builtin_elementwise_min:
11980 ResultElements.push_back(
11987 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
11989 case X86::BI__builtin_ia32_selectb_128:
11990 case X86::BI__builtin_ia32_selectb_256:
11991 case X86::BI__builtin_ia32_selectb_512:
11992 case X86::BI__builtin_ia32_selectw_128:
11993 case X86::BI__builtin_ia32_selectw_256:
11994 case X86::BI__builtin_ia32_selectw_512:
11995 case X86::BI__builtin_ia32_selectd_128:
11996 case X86::BI__builtin_ia32_selectd_256:
11997 case X86::BI__builtin_ia32_selectd_512:
11998 case X86::BI__builtin_ia32_selectq_128:
11999 case X86::BI__builtin_ia32_selectq_256:
12000 case X86::BI__builtin_ia32_selectq_512:
12001 case X86::BI__builtin_ia32_selectph_128:
12002 case X86::BI__builtin_ia32_selectph_256:
12003 case X86::BI__builtin_ia32_selectph_512:
12004 case X86::BI__builtin_ia32_selectpbf_128:
12005 case X86::BI__builtin_ia32_selectpbf_256:
12006 case X86::BI__builtin_ia32_selectpbf_512:
12007 case X86::BI__builtin_ia32_selectps_128:
12008 case X86::BI__builtin_ia32_selectps_256:
12009 case X86::BI__builtin_ia32_selectps_512:
12010 case X86::BI__builtin_ia32_selectpd_128:
12011 case X86::BI__builtin_ia32_selectpd_256:
12012 case X86::BI__builtin_ia32_selectpd_512: {
12014 APValue SourceMask, SourceLHS, SourceRHS;
12023 ResultElements.reserve(SourceLen);
12025 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12028 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
12031 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12033 case Builtin::BI__builtin_elementwise_ctlz:
12034 case Builtin::BI__builtin_elementwise_cttz: {
12036 std::optional<APValue> Fallback;
12039 if (
E->getNumArgs() > 1) {
12043 Fallback = FallbackTmp;
12049 ResultElements.reserve(SourceLen);
12051 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12056 Info.FFDiag(
E, diag::note_constexpr_countzeroes_zero)
12057 << (
E->getBuiltinCallee() ==
12058 Builtin::BI__builtin_elementwise_cttz);
12061 ResultElements.push_back(Fallback->getVectorElt(EltNum));
12064 switch (
E->getBuiltinCallee()) {
12065 case Builtin::BI__builtin_elementwise_ctlz:
12066 ResultElements.push_back(
APValue(
12067 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
12070 case Builtin::BI__builtin_elementwise_cttz:
12071 ResultElements.push_back(
APValue(
12072 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
12078 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12081 case Builtin::BI__builtin_elementwise_fma: {
12082 APValue SourceX, SourceY, SourceZ;
12090 ResultElements.reserve(SourceLen);
12092 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12097 (void)Result.fusedMultiplyAdd(Y, Z, RM);
12098 ResultElements.push_back(
APValue(Result));
12100 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12118 ResultElements.reserve(SourceLen);
12119 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12124 ResultElements.push_back(std::move(Elt));
12127 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12132 APValue const &VecVal2,
unsigned EltNum,
12134 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
12135 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
12137 APSInt IndexVal =
E->getShuffleMaskIdx(EltNum);
12138 int64_t index = IndexVal.getExtValue();
12145 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
12151 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
12152 llvm_unreachable(
"Out of bounds shuffle index");
12154 if (index >= TotalElementsInInputVector1)
12155 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
12163 const Expr *Vec1 =
E->getExpr(0);
12167 const Expr *Vec2 =
E->getExpr(1);
12177 ResultElements.reserve(TotalElementsInOutputVector);
12178 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
12182 ResultElements.push_back(std::move(Elt));
12185 return Success(
APValue(ResultElements.data(), ResultElements.size()),
E);
12193 class ArrayExprEvaluator
12194 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
12195 const LValue &
This;
12199 ArrayExprEvaluator(EvalInfo &Info,
const LValue &
This,
APValue &Result)
12200 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
12203 assert(
V.isArray() &&
"expected array");
12208 bool ZeroInitialization(
const Expr *
E) {
12210 Info.Ctx.getAsConstantArrayType(
E->
getType());
12224 if (!Result.hasArrayFiller())
12228 LValue Subobject =
This;
12229 Subobject.addArray(Info,
E, CAT);
12231 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
12234 bool VisitCallExpr(
const CallExpr *
E) {
12235 return handleCallExpr(
E, Result, &
This);
12242 const LValue &Subobject,
12250 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
12252 const Expr *ArrayFiller,
12258 APValue &Result, EvalInfo &Info) {
12261 "not an array prvalue");
12262 return ArrayExprEvaluator(Info,
This, Result).Visit(
E);
12270 "not an array prvalue");
12271 return ArrayExprEvaluator(Info,
This, Result)
12272 .VisitInitListExpr(ILE, AllocType);
12281 "not an array prvalue");
12282 return ArrayExprEvaluator(Info,
This, Result)
12283 .VisitCXXConstructExpr(CCE,
This, &Result, AllocType);
12290 if (isa<ImplicitValueInitExpr>(FillerExpr))
12292 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
12293 for (
unsigned I = 0,
E = ILE->getNumInits(); I !=
E; ++I) {
12298 if (ILE->hasArrayFiller() &&
12307bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *
E,
12316 if (
E->isStringLiteralInit()) {
12322 return VisitStringLiteral(SL, AllocType);
12326 assert(!
E->isTransparent() &&
12327 "transparent array list initialization is not string literal init?");
12329 return VisitCXXParenListOrInitListExpr(
E,
E->inits(),
E->getArrayFiller(),
12333bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
12341 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
12342 "zero-initialized array shouldn't have any initialized elts");
12344 if (Result.isArray() && Result.hasArrayFiller())
12345 Filler = Result.getArrayFiller();
12347 unsigned NumEltsToInit = Args.size();
12352 if (NumEltsToInit != NumElts &&
12354 NumEltsToInit = NumElts;
12356 for (
auto *
Init : Args) {
12357 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
12358 NumEltsToInit += EmbedS->getDataElementCount() - 1;
12360 if (NumEltsToInit > NumElts)
12361 NumEltsToInit = NumElts;
12364 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
12365 << NumEltsToInit <<
".\n");
12372 for (
unsigned I = 0,
E = Result.getArrayInitializedElts(); I !=
E; ++I)
12373 Result.getArrayInitializedElt(I) = Filler;
12374 if (Result.hasArrayFiller())
12375 Result.getArrayFiller() = Filler;
12378 LValue Subobject =
This;
12379 Subobject.addArray(Info, ExprToVisit, CAT);
12380 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
12381 if (
Init->isValueDependent())
12384 if (!
EvaluateInPlace(Result.getArrayInitializedElt(ArrayIndex), Info,
12385 Subobject,
Init) ||
12388 if (!Info.noteFailure())
12394 unsigned ArrayIndex = 0;
12397 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
12398 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
12399 if (ArrayIndex >= NumEltsToInit)
12401 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
12403 for (
unsigned I = EmbedS->getStartingElementPos(),
12404 N = EmbedS->getDataElementCount();
12405 I != EmbedS->getStartingElementPos() + N; ++I) {
12408 Result.getArrayInitializedElt(ArrayIndex) =
APValue(
Value);
12412 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
12417 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
12422 if (!Eval(
Init, ArrayIndex))
12428 if (!Result.hasArrayFiller())
12433 assert(ArrayFiller &&
"no array filler for incomplete init list");
12441 if (
E->getCommonExpr() &&
12442 !
Evaluate(Info.CurrentCall->createTemporary(
12443 E->getCommonExpr(),
12444 getStorageType(Info.Ctx,
E->getCommonExpr()),
12445 ScopeKind::FullExpression, CommonLV),
12446 Info,
E->getCommonExpr()->getSourceExpr()))
12454 LValue Subobject =
This;
12455 Subobject.addArray(Info,
E, CAT);
12458 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
12467 FullExpressionRAII
Scope(Info);
12470 Info, Subobject,
E->getSubExpr()) ||
12473 if (!Info.noteFailure())
12486 return VisitCXXConstructExpr(
E,
This, &Result,
E->
getType());
12490 const LValue &Subobject,
12500 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
12504 if (FinalSize == 0)
12509 E->requiresZeroInitialization());
12510 LValue ArrayElt = Subobject;
12511 ArrayElt.addArray(Info,
E, CAT);
12517 for (
const unsigned N : {1u, FinalSize}) {
12518 unsigned OldElts =
Value->getArrayInitializedElts();
12524 for (
unsigned I = 0; I < OldElts; ++I)
12525 NewValue.getArrayInitializedElt(I).swap(
12526 Value->getArrayInitializedElt(I));
12527 Value->swap(NewValue);
12530 for (
unsigned I = OldElts; I < N; ++I)
12531 Value->getArrayInitializedElt(I) = Filler;
12533 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
12536 APValue &FirstResult =
Value->getArrayInitializedElt(0);
12537 for (
unsigned I = OldElts; I < FinalSize; ++I)
12538 Value->getArrayInitializedElt(I) = FirstResult;
12540 for (
unsigned I = OldElts; I < N; ++I) {
12541 if (!VisitCXXConstructExpr(
E, ArrayElt,
12542 &
Value->getArrayInitializedElt(I),
12549 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
12550 !Info.keepEvaluatingAfterFailure())
12562 return RecordExprEvaluator(Info, Subobject, *
Value)
12563 .VisitCXXConstructExpr(
E,
Type);
12566bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
12569 "Expression result is not a constant array type");
12571 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs(),
12572 E->getArrayFiller());
12584class IntExprEvaluator
12585 :
public ExprEvaluatorBase<IntExprEvaluator> {
12588 IntExprEvaluator(EvalInfo &info,
APValue &result)
12589 : ExprEvaluatorBaseTy(info), Result(result) {}
12593 "Invalid evaluation result.");
12595 "Invalid evaluation result.");
12596 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12597 "Invalid evaluation result.");
12607 "Invalid evaluation result.");
12608 assert(I.getBitWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12609 "Invalid evaluation result.");
12611 Result.getInt().setIsUnsigned(
12621 "Invalid evaluation result.");
12636 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
12637 V.allowConstexprUnknown()) {
12644 bool ZeroInitialization(
const Expr *
E) {
return Success(0,
E); }
12646 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
12660 bool CheckReferencedDecl(
const Expr *
E,
const Decl *
D);
12662 if (CheckReferencedDecl(
E,
E->getDecl()))
12665 return ExprEvaluatorBaseTy::VisitDeclRefExpr(
E);
12668 if (CheckReferencedDecl(
E,
E->getMemberDecl())) {
12669 VisitIgnoredBaseExpression(
E->getBase());
12673 return ExprEvaluatorBaseTy::VisitMemberExpr(
E);
12677 bool VisitBuiltinCallExpr(
const CallExpr *
E,
unsigned BuiltinOp);
12694 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
12700 return Success(Info.ArrayInitIndex,
E);
12705 return ZeroInitialization(
E);
12709 if (
E->isStoredAsBoolean())
12711 if (
E->getAPValue().isAbsent())
12713 assert(
E->getAPValue().isInt() &&
"APValue type not supported");
12714 return Success(
E->getAPValue().getInt(),
E);
12743class FixedPointExprEvaluator
12744 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
12748 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
12749 : ExprEvaluatorBaseTy(info), Result(result) {}
12753 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12758 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(
E->
getType())),
E);
12767 assert(
V.getWidth() == Info.Ctx.getIntWidth(
E->
getType()) &&
12768 "Invalid evaluation result.");
12773 bool ZeroInitialization(
const Expr *
E) {
12803 return IntExprEvaluator(Info, Result).Visit(
E);
12811 if (!Val.
isInt()) {
12814 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
12821bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *
E) {
12823 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
12832 if (!FixedPointExprEvaluator(Info, Val).Visit(
E))
12847 auto FXSema = Info.Ctx.getFixedPointSemantics(
E->
getType());
12851 Result = APFixedPoint(Val, FXSema);
12862bool IntExprEvaluator::CheckReferencedDecl(
const Expr*
E,
const Decl*
D) {
12866 bool SameSign = (ECD->getInitVal().isSigned()
12868 bool SameWidth = (ECD->getInitVal().getBitWidth()
12869 == Info.Ctx.getIntWidth(
E->
getType()));
12870 if (SameSign && SameWidth)
12871 return Success(ECD->getInitVal(),
E);
12875 llvm::APSInt Val = ECD->getInitVal();
12877 Val.setIsSigned(!ECD->getInitVal().isSigned());
12879 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(
E->
getType()));
12895#define TYPE(ID, BASE)
12896#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
12897#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
12898#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
12899#include "clang/AST/TypeNodes.inc"
12901 case Type::DeducedTemplateSpecialization:
12902 llvm_unreachable(
"unexpected non-canonical or dependent type");
12904 case Type::Builtin:
12905 switch (cast<BuiltinType>(CanTy)->
getKind()) {
12906#define BUILTIN_TYPE(ID, SINGLETON_ID)
12907#define SIGNED_TYPE(ID, SINGLETON_ID) \
12908 case BuiltinType::ID: return GCCTypeClass::Integer;
12909#define FLOATING_TYPE(ID, SINGLETON_ID) \
12910 case BuiltinType::ID: return GCCTypeClass::RealFloat;
12911#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
12912 case BuiltinType::ID: break;
12913#include "clang/AST/BuiltinTypes.def"
12914 case BuiltinType::Void:
12915 return GCCTypeClass::Void;
12917 case BuiltinType::Bool:
12918 return GCCTypeClass::Bool;
12920 case BuiltinType::Char_U:
12921 case BuiltinType::UChar:
12922 case BuiltinType::WChar_U:
12923 case BuiltinType::Char8:
12924 case BuiltinType::Char16:
12925 case BuiltinType::Char32:
12926 case BuiltinType::UShort:
12927 case BuiltinType::UInt:
12928 case BuiltinType::ULong:
12929 case BuiltinType::ULongLong:
12930 case BuiltinType::UInt128:
12931 return GCCTypeClass::Integer;
12933 case BuiltinType::UShortAccum:
12934 case BuiltinType::UAccum:
12935 case BuiltinType::ULongAccum:
12936 case BuiltinType::UShortFract:
12937 case BuiltinType::UFract:
12938 case BuiltinType::ULongFract:
12939 case BuiltinType::SatUShortAccum:
12940 case BuiltinType::SatUAccum:
12941 case BuiltinType::SatULongAccum:
12942 case BuiltinType::SatUShortFract:
12943 case BuiltinType::SatUFract:
12944 case BuiltinType::SatULongFract:
12945 return GCCTypeClass::None;
12947 case BuiltinType::NullPtr:
12949 case BuiltinType::ObjCId:
12950 case BuiltinType::ObjCClass:
12951 case BuiltinType::ObjCSel:
12952#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
12953 case BuiltinType::Id:
12954#include "clang/Basic/OpenCLImageTypes.def"
12955#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
12956 case BuiltinType::Id:
12957#include "clang/Basic/OpenCLExtensionTypes.def"
12958 case BuiltinType::OCLSampler:
12959 case BuiltinType::OCLEvent:
12960 case BuiltinType::OCLClkEvent:
12961 case BuiltinType::OCLQueue:
12962 case BuiltinType::OCLReserveID:
12963#define SVE_TYPE(Name, Id, SingletonId) \
12964 case BuiltinType::Id:
12965#include "clang/Basic/AArch64ACLETypes.def"
12966#define PPC_VECTOR_TYPE(Name, Id, Size) \
12967 case BuiltinType::Id:
12968#include "clang/Basic/PPCTypes.def"
12969#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12970#include "clang/Basic/RISCVVTypes.def"
12971#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12972#include "clang/Basic/WebAssemblyReferenceTypes.def"
12973#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
12974#include "clang/Basic/AMDGPUTypes.def"
12975#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
12976#include "clang/Basic/HLSLIntangibleTypes.def"
12977 return GCCTypeClass::None;
12979 case BuiltinType::Dependent:
12980 llvm_unreachable(
"unexpected dependent type");
12982 llvm_unreachable(
"unexpected placeholder type");
12985 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
12987 case Type::Pointer:
12988 case Type::ConstantArray:
12989 case Type::VariableArray:
12990 case Type::IncompleteArray:
12991 case Type::FunctionNoProto:
12992 case Type::FunctionProto:
12993 case Type::ArrayParameter:
12994 return GCCTypeClass::Pointer;
12996 case Type::MemberPointer:
12998 ? GCCTypeClass::PointerToDataMember
12999 : GCCTypeClass::PointerToMemberFunction;
13001 case Type::Complex:
13002 return GCCTypeClass::Complex;
13005 return CanTy->
isUnionType() ? GCCTypeClass::Union
13006 : GCCTypeClass::ClassOrStruct;
13014 case Type::ExtVector:
13015 return GCCTypeClass::Vector;
13017 case Type::BlockPointer:
13018 case Type::ConstantMatrix:
13019 case Type::ObjCObject:
13020 case Type::ObjCInterface:
13021 case Type::ObjCObjectPointer:
13023 case Type::HLSLAttributedResource:
13024 case Type::HLSLInlineSpirv:
13027 return GCCTypeClass::None;
13030 return GCCTypeClass::BitInt;
13032 case Type::LValueReference:
13033 case Type::RValueReference:
13034 llvm_unreachable(
"invalid type for expression");
13037 llvm_unreachable(
"unexpected type class");
13046 if (
E->getNumArgs() == 0)
13047 return GCCTypeClass::None;
13062 if (
Base.isNull()) {
13065 }
else if (
const Expr *
E =
Base.dyn_cast<
const Expr *>()) {
13066 if (!isa<StringLiteral>(
E))
13084 SpeculativeEvaluationRAII SpeculativeEval(Info);
13089 FoldConstant Fold(Info,
true);
13112 Fold.keepDiagnostics();
13121 return V.hasValue();
13132 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
13135 if (isa<CompoundLiteralExpr>(
E))
13156 const auto *Cast = dyn_cast<CastExpr>(NoParens);
13157 if (Cast ==
nullptr)
13162 auto CastKind = Cast->getCastKind();
13164 CastKind != CK_AddressSpaceConversion)
13167 const auto *SubExpr = Cast->getSubExpr();
13189 assert(!LVal.Designator.Invalid);
13191 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
13199 auto &
Base = LVal.getLValueBase();
13200 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
13201 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
13202 if (!IsLastOrInvalidFieldDecl(FD))
13204 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
13205 for (
auto *FD : IFD->chain()) {
13206 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD)))
13214 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
13224 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++I) {
13225 const auto &Entry = LVal.Designator.Entries[I];
13231 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
13232 uint64_t Index = Entry.getAsArrayIndex();
13238 uint64_t Index = Entry.getAsArrayIndex();
13241 BaseType = CT->getElementType();
13242 }
else if (
auto *FD = getAsField(Entry)) {
13243 if (!IsLastOrInvalidFieldDecl(FD))
13247 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
13259 if (LVal.Designator.Invalid)
13262 if (!LVal.Designator.Entries.empty())
13263 return LVal.Designator.isMostDerivedAnUnsizedArray();
13265 if (!LVal.InvalidBase)
13270 const auto *
E = LVal.Base.dyn_cast<
const Expr *>();
13271 return !
E || !isa<MemberExpr>(
E);
13277 const SubobjectDesignator &
Designator = LVal.Designator;
13289 auto isFlexibleArrayMember = [&] {
13291 FAMKind StrictFlexArraysLevel =
13294 if (
Designator.isMostDerivedAnUnsizedArray())
13297 if (StrictFlexArraysLevel == FAMKind::Default)
13300 if (
Designator.getMostDerivedArraySize() == 0 &&
13301 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
13304 if (
Designator.getMostDerivedArraySize() == 1 &&
13305 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
13311 return LVal.InvalidBase &&
13313 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
13321 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
13322 if (Int.ugt(CharUnitsMax))
13334 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
13335 if (
const auto *VD = dyn_cast<VarDecl>(
V))
13347 unsigned Type,
const LValue &LVal,
13366 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
13368 if (
Type == 3 && !DetermineForCompleteObject)
13371 llvm::APInt APEndOffset;
13372 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13376 if (LVal.InvalidBase)
13380 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
13386 const SubobjectDesignator &
Designator = LVal.Designator;
13398 llvm::APInt APEndOffset;
13399 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
13411 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
13417 int64_t ElemsRemaining;
13420 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
13421 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
13422 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
13424 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
13427 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
13437 EvalInfo &Info, uint64_t &Size) {
13444 SpeculativeEvaluationRAII SpeculativeEval(Info);
13445 IgnoreSideEffectsRAII Fold(Info);
13453 LVal.setFrom(Info.Ctx, RVal);
13461 if (LVal.getLValueOffset().isNegative()) {
13472 if (EndOffset <= LVal.getLValueOffset())
13475 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
13479bool IntExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
13480 if (!IsConstantEvaluatedBuiltinCall(
E))
13481 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
13482 return VisitBuiltinCallExpr(
E,
E->getBuiltinCallee());
13498 Info.FFDiag(
E->getArg(0));
13504 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
13505 "Bit widths must be the same");
13512bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *
E,
13513 unsigned BuiltinOp) {
13514 switch (BuiltinOp) {
13518 case Builtin::BI__builtin_dynamic_object_size:
13519 case Builtin::BI__builtin_object_size: {
13523 assert(
Type <= 3 &&
"unexpected type");
13534 switch (Info.EvalMode) {
13535 case EvalInfo::EM_ConstantExpression:
13536 case EvalInfo::EM_ConstantFold:
13537 case EvalInfo::EM_IgnoreSideEffects:
13540 case EvalInfo::EM_ConstantExpressionUnevaluated:
13545 llvm_unreachable(
"unexpected EvalMode");
13548 case Builtin::BI__builtin_os_log_format_buffer_size: {
13554 case Builtin::BI__builtin_is_aligned: {
13562 Ptr.setFrom(Info.Ctx, Src);
13568 assert(Alignment.isPowerOf2());
13581 Info.FFDiag(
E->getArg(0), diag::note_constexpr_alignment_compute)
13585 assert(Src.
isInt());
13586 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0,
E);
13588 case Builtin::BI__builtin_align_up: {
13596 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
13597 Src.
getInt().isUnsigned());
13598 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13601 case Builtin::BI__builtin_align_down: {
13610 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
13614 case Builtin::BI__builtin_bitreverse8:
13615 case Builtin::BI__builtin_bitreverse16:
13616 case Builtin::BI__builtin_bitreverse32:
13617 case Builtin::BI__builtin_bitreverse64:
13618 case Builtin::BI__builtin_elementwise_bitreverse: {
13623 return Success(Val.reverseBits(),
E);
13626 case Builtin::BI__builtin_bswap16:
13627 case Builtin::BI__builtin_bswap32:
13628 case Builtin::BI__builtin_bswap64: {
13633 return Success(Val.byteSwap(),
E);
13636 case Builtin::BI__builtin_classify_type:
13639 case Builtin::BI__builtin_clrsb:
13640 case Builtin::BI__builtin_clrsbl:
13641 case Builtin::BI__builtin_clrsbll: {
13646 return Success(Val.getBitWidth() - Val.getSignificantBits(),
E);
13649 case Builtin::BI__builtin_clz:
13650 case Builtin::BI__builtin_clzl:
13651 case Builtin::BI__builtin_clzll:
13652 case Builtin::BI__builtin_clzs:
13653 case Builtin::BI__builtin_clzg:
13654 case Builtin::BI__builtin_elementwise_ctlz:
13655 case Builtin::BI__lzcnt16:
13656 case Builtin::BI__lzcnt:
13657 case Builtin::BI__lzcnt64: {
13668 std::optional<APSInt> Fallback;
13669 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
13670 BuiltinOp == Builtin::BI__builtin_elementwise_ctlz) &&
13671 E->getNumArgs() > 1) {
13675 Fallback = FallbackTemp;
13685 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
13686 BuiltinOp != Builtin::BI__lzcnt &&
13687 BuiltinOp != Builtin::BI__lzcnt64;
13689 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctlz) {
13690 Info.FFDiag(
E, diag::note_constexpr_countzeroes_zero)
13694 if (ZeroIsUndefined)
13698 return Success(Val.countl_zero(),
E);
13701 case Builtin::BI__builtin_constant_p: {
13702 const Expr *Arg =
E->getArg(0);
13711 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
13715 case Builtin::BI__noop:
13719 case Builtin::BI__builtin_is_constant_evaluated: {
13720 const auto *
Callee = Info.CurrentCall->getCallee();
13721 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
13722 (Info.CallStackDepth == 1 ||
13723 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
13724 Callee->getIdentifier() &&
13725 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
13727 if (Info.EvalStatus.Diag)
13728 Info.report((Info.CallStackDepth == 1)
13730 : Info.CurrentCall->getCallRange().getBegin(),
13731 diag::warn_is_constant_evaluated_always_true_constexpr)
13732 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
13733 :
"std::is_constant_evaluated");
13736 return Success(Info.InConstantContext,
E);
13739 case Builtin::BI__builtin_is_within_lifetime:
13740 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this,
E))
13744 case Builtin::BI__builtin_ctz:
13745 case Builtin::BI__builtin_ctzl:
13746 case Builtin::BI__builtin_ctzll:
13747 case Builtin::BI__builtin_ctzs:
13748 case Builtin::BI__builtin_ctzg:
13749 case Builtin::BI__builtin_elementwise_cttz: {
13760 std::optional<APSInt> Fallback;
13761 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
13762 BuiltinOp == Builtin::BI__builtin_elementwise_cttz) &&
13763 E->getNumArgs() > 1) {
13767 Fallback = FallbackTemp;
13774 if (BuiltinOp == Builtin::BI__builtin_elementwise_cttz) {
13775 Info.FFDiag(
E, diag::note_constexpr_countzeroes_zero)
13781 return Success(Val.countr_zero(),
E);
13784 case Builtin::BI__builtin_eh_return_data_regno: {
13786 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
13790 case Builtin::BI__builtin_elementwise_abs: {
13798 case Builtin::BI__builtin_expect:
13799 case Builtin::BI__builtin_expect_with_probability:
13800 return Visit(
E->getArg(0));
13802 case Builtin::BI__builtin_ptrauth_string_discriminator: {
13809 case Builtin::BI__builtin_ffs:
13810 case Builtin::BI__builtin_ffsl:
13811 case Builtin::BI__builtin_ffsll: {
13816 unsigned N = Val.countr_zero();
13817 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
13820 case Builtin::BI__builtin_fpclassify: {
13825 switch (Val.getCategory()) {
13826 case APFloat::fcNaN: Arg = 0;
break;
13827 case APFloat::fcInfinity: Arg = 1;
break;
13828 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
13829 case APFloat::fcZero: Arg = 4;
break;
13831 return Visit(
E->getArg(Arg));
13834 case Builtin::BI__builtin_isinf_sign: {
13837 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0,
E);
13840 case Builtin::BI__builtin_isinf: {
13843 Success(Val.isInfinity() ? 1 : 0,
E);
13846 case Builtin::BI__builtin_isfinite: {
13849 Success(Val.isFinite() ? 1 : 0,
E);
13852 case Builtin::BI__builtin_isnan: {
13858 case Builtin::BI__builtin_isnormal: {
13861 Success(Val.isNormal() ? 1 : 0,
E);
13864 case Builtin::BI__builtin_issubnormal: {
13867 Success(Val.isDenormal() ? 1 : 0,
E);
13870 case Builtin::BI__builtin_iszero: {
13876 case Builtin::BI__builtin_signbit:
13877 case Builtin::BI__builtin_signbitf:
13878 case Builtin::BI__builtin_signbitl: {
13881 Success(Val.isNegative() ? 1 : 0,
E);
13884 case Builtin::BI__builtin_isgreater:
13885 case Builtin::BI__builtin_isgreaterequal:
13886 case Builtin::BI__builtin_isless:
13887 case Builtin::BI__builtin_islessequal:
13888 case Builtin::BI__builtin_islessgreater:
13889 case Builtin::BI__builtin_isunordered: {
13898 switch (BuiltinOp) {
13899 case Builtin::BI__builtin_isgreater:
13901 case Builtin::BI__builtin_isgreaterequal:
13903 case Builtin::BI__builtin_isless:
13905 case Builtin::BI__builtin_islessequal:
13907 case Builtin::BI__builtin_islessgreater: {
13908 APFloat::cmpResult cmp = LHS.compare(RHS);
13909 return cmp == APFloat::cmpResult::cmpLessThan ||
13910 cmp == APFloat::cmpResult::cmpGreaterThan;
13912 case Builtin::BI__builtin_isunordered:
13913 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
13915 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
13916 "point comparison function");
13924 case Builtin::BI__builtin_issignaling: {
13927 Success(Val.isSignaling() ? 1 : 0,
E);
13930 case Builtin::BI__builtin_isfpclass: {
13934 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
13937 Success((Val.classify() & Test) ? 1 : 0,
E);
13940 case Builtin::BI__builtin_parity:
13941 case Builtin::BI__builtin_parityl:
13942 case Builtin::BI__builtin_parityll: {
13947 return Success(Val.popcount() % 2,
E);
13950 case Builtin::BI__builtin_abs:
13951 case Builtin::BI__builtin_labs:
13952 case Builtin::BI__builtin_llabs: {
13956 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
13959 if (Val.isNegative())
13964 case Builtin::BI__builtin_popcount:
13965 case Builtin::BI__builtin_popcountl:
13966 case Builtin::BI__builtin_popcountll:
13967 case Builtin::BI__builtin_popcountg:
13968 case Builtin::BI__builtin_elementwise_popcount:
13969 case Builtin::BI__popcnt16:
13970 case Builtin::BI__popcnt:
13971 case Builtin::BI__popcnt64: {
13982 return Success(Val.popcount(),
E);
13985 case Builtin::BI__builtin_rotateleft8:
13986 case Builtin::BI__builtin_rotateleft16:
13987 case Builtin::BI__builtin_rotateleft32:
13988 case Builtin::BI__builtin_rotateleft64:
13989 case Builtin::BI_rotl8:
13990 case Builtin::BI_rotl16:
13991 case Builtin::BI_rotl:
13992 case Builtin::BI_lrotl:
13993 case Builtin::BI_rotl64: {
13999 return Success(Val.rotl(Amt.urem(Val.getBitWidth())),
E);
14002 case Builtin::BI__builtin_rotateright8:
14003 case Builtin::BI__builtin_rotateright16:
14004 case Builtin::BI__builtin_rotateright32:
14005 case Builtin::BI__builtin_rotateright64:
14006 case Builtin::BI_rotr8:
14007 case Builtin::BI_rotr16:
14008 case Builtin::BI_rotr:
14009 case Builtin::BI_lrotr:
14010 case Builtin::BI_rotr64: {
14016 return Success(Val.rotr(Amt.urem(Val.getBitWidth())),
E);
14019 case Builtin::BI__builtin_elementwise_add_sat: {
14025 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
14028 case Builtin::BI__builtin_elementwise_sub_sat: {
14034 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
14037 case Builtin::BI__builtin_elementwise_max: {
14043 APInt Result = std::max(LHS, RHS);
14046 case Builtin::BI__builtin_elementwise_min: {
14052 APInt Result = std::min(LHS, RHS);
14055 case Builtin::BIstrlen:
14056 case Builtin::BIwcslen:
14058 if (Info.getLangOpts().CPlusPlus11)
14059 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
14061 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
14063 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14065 case Builtin::BI__builtin_strlen:
14066 case Builtin::BI__builtin_wcslen: {
14075 case Builtin::BIstrcmp:
14076 case Builtin::BIwcscmp:
14077 case Builtin::BIstrncmp:
14078 case Builtin::BIwcsncmp:
14079 case Builtin::BImemcmp:
14080 case Builtin::BIbcmp:
14081 case Builtin::BIwmemcmp:
14083 if (Info.getLangOpts().CPlusPlus11)
14084 Info.CCEDiag(
E, diag::note_constexpr_invalid_function)
14086 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
14088 Info.CCEDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14090 case Builtin::BI__builtin_strcmp:
14091 case Builtin::BI__builtin_wcscmp:
14092 case Builtin::BI__builtin_strncmp:
14093 case Builtin::BI__builtin_wcsncmp:
14094 case Builtin::BI__builtin_memcmp:
14095 case Builtin::BI__builtin_bcmp:
14096 case Builtin::BI__builtin_wmemcmp: {
14097 LValue String1, String2;
14103 if (BuiltinOp != Builtin::BIstrcmp &&
14104 BuiltinOp != Builtin::BIwcscmp &&
14105 BuiltinOp != Builtin::BI__builtin_strcmp &&
14106 BuiltinOp != Builtin::BI__builtin_wcscmp) {
14110 MaxLength = N.getZExtValue();
14114 if (MaxLength == 0u)
14117 if (!String1.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
14118 !String2.checkNullPointerForFoldAccess(Info,
E,
AK_Read) ||
14119 String1.Designator.Invalid || String2.Designator.Invalid)
14122 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
14123 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
14125 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
14126 BuiltinOp == Builtin::BIbcmp ||
14127 BuiltinOp == Builtin::BI__builtin_memcmp ||
14128 BuiltinOp == Builtin::BI__builtin_bcmp;
14130 assert(IsRawByte ||
14131 (Info.Ctx.hasSameUnqualifiedType(
14133 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
14140 Info.FFDiag(
E, diag::note_constexpr_memcmp_unsupported)
14141 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
14146 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
14149 Char1.
isInt() && Char2.isInt();
14151 const auto &AdvanceElems = [&] {
14157 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
14158 BuiltinOp != Builtin::BIwmemcmp &&
14159 BuiltinOp != Builtin::BI__builtin_memcmp &&
14160 BuiltinOp != Builtin::BI__builtin_bcmp &&
14161 BuiltinOp != Builtin::BI__builtin_wmemcmp);
14162 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
14163 BuiltinOp == Builtin::BIwcsncmp ||
14164 BuiltinOp == Builtin::BIwmemcmp ||
14165 BuiltinOp == Builtin::BI__builtin_wcscmp ||
14166 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
14167 BuiltinOp == Builtin::BI__builtin_wmemcmp;
14169 for (; MaxLength; --MaxLength) {
14171 if (!ReadCurElems(Char1, Char2))
14179 if (StopAtNull && !Char1.
getInt())
14181 assert(!(StopAtNull && !Char2.
getInt()));
14182 if (!AdvanceElems())
14189 case Builtin::BI__atomic_always_lock_free:
14190 case Builtin::BI__atomic_is_lock_free:
14191 case Builtin::BI__c11_atomic_is_lock_free: {
14207 if (
Size.isPowerOfTwo()) {
14209 unsigned InlineWidthBits =
14210 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
14211 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
14212 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
14218 const Expr *PtrArg =
E->getArg(1);
14224 IntResult.isAligned(
Size.getAsAlign()))
14228 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
14231 if (ICE->getCastKind() == CK_BitCast)
14232 PtrArg = ICE->getSubExpr();
14238 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
14246 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
14249 case Builtin::BI__builtin_addcb:
14250 case Builtin::BI__builtin_addcs:
14251 case Builtin::BI__builtin_addc:
14252 case Builtin::BI__builtin_addcl:
14253 case Builtin::BI__builtin_addcll:
14254 case Builtin::BI__builtin_subcb:
14255 case Builtin::BI__builtin_subcs:
14256 case Builtin::BI__builtin_subc:
14257 case Builtin::BI__builtin_subcl:
14258 case Builtin::BI__builtin_subcll: {
14259 LValue CarryOutLValue;
14260 APSInt LHS, RHS, CarryIn, CarryOut, Result;
14271 bool FirstOverflowed =
false;
14272 bool SecondOverflowed =
false;
14273 switch (BuiltinOp) {
14275 llvm_unreachable(
"Invalid value for BuiltinOp");
14276 case Builtin::BI__builtin_addcb:
14277 case Builtin::BI__builtin_addcs:
14278 case Builtin::BI__builtin_addc:
14279 case Builtin::BI__builtin_addcl:
14280 case Builtin::BI__builtin_addcll:
14282 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
14284 case Builtin::BI__builtin_subcb:
14285 case Builtin::BI__builtin_subcs:
14286 case Builtin::BI__builtin_subc:
14287 case Builtin::BI__builtin_subcl:
14288 case Builtin::BI__builtin_subcll:
14290 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
14296 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
14302 case Builtin::BI__builtin_add_overflow:
14303 case Builtin::BI__builtin_sub_overflow:
14304 case Builtin::BI__builtin_mul_overflow:
14305 case Builtin::BI__builtin_sadd_overflow:
14306 case Builtin::BI__builtin_uadd_overflow:
14307 case Builtin::BI__builtin_uaddl_overflow:
14308 case Builtin::BI__builtin_uaddll_overflow:
14309 case Builtin::BI__builtin_usub_overflow:
14310 case Builtin::BI__builtin_usubl_overflow:
14311 case Builtin::BI__builtin_usubll_overflow:
14312 case Builtin::BI__builtin_umul_overflow:
14313 case Builtin::BI__builtin_umull_overflow:
14314 case Builtin::BI__builtin_umulll_overflow:
14315 case Builtin::BI__builtin_saddl_overflow:
14316 case Builtin::BI__builtin_saddll_overflow:
14317 case Builtin::BI__builtin_ssub_overflow:
14318 case Builtin::BI__builtin_ssubl_overflow:
14319 case Builtin::BI__builtin_ssubll_overflow:
14320 case Builtin::BI__builtin_smul_overflow:
14321 case Builtin::BI__builtin_smull_overflow:
14322 case Builtin::BI__builtin_smulll_overflow: {
14323 LValue ResultLValue;
14333 bool DidOverflow =
false;
14336 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14337 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14338 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14339 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
14341 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
14343 uint64_t LHSSize = LHS.getBitWidth();
14344 uint64_t RHSSize = RHS.getBitWidth();
14345 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
14346 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
14352 if (IsSigned && !AllSigned)
14355 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
14356 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
14357 Result =
APSInt(MaxBits, !IsSigned);
14361 switch (BuiltinOp) {
14363 llvm_unreachable(
"Invalid value for BuiltinOp");
14364 case Builtin::BI__builtin_add_overflow:
14365 case Builtin::BI__builtin_sadd_overflow:
14366 case Builtin::BI__builtin_saddl_overflow:
14367 case Builtin::BI__builtin_saddll_overflow:
14368 case Builtin::BI__builtin_uadd_overflow:
14369 case Builtin::BI__builtin_uaddl_overflow:
14370 case Builtin::BI__builtin_uaddll_overflow:
14371 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
14372 : LHS.uadd_ov(RHS, DidOverflow);
14374 case Builtin::BI__builtin_sub_overflow:
14375 case Builtin::BI__builtin_ssub_overflow:
14376 case Builtin::BI__builtin_ssubl_overflow:
14377 case Builtin::BI__builtin_ssubll_overflow:
14378 case Builtin::BI__builtin_usub_overflow:
14379 case Builtin::BI__builtin_usubl_overflow:
14380 case Builtin::BI__builtin_usubll_overflow:
14381 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
14382 : LHS.usub_ov(RHS, DidOverflow);
14384 case Builtin::BI__builtin_mul_overflow:
14385 case Builtin::BI__builtin_smul_overflow:
14386 case Builtin::BI__builtin_smull_overflow:
14387 case Builtin::BI__builtin_smulll_overflow:
14388 case Builtin::BI__builtin_umul_overflow:
14389 case Builtin::BI__builtin_umull_overflow:
14390 case Builtin::BI__builtin_umulll_overflow:
14391 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
14392 : LHS.umul_ov(RHS, DidOverflow);
14398 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
14399 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
14400 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
14406 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
14409 if (!APSInt::isSameValue(Temp, Result))
14410 DidOverflow =
true;
14420 case Builtin::BI__builtin_reduce_add:
14421 case Builtin::BI__builtin_reduce_mul:
14422 case Builtin::BI__builtin_reduce_and:
14423 case Builtin::BI__builtin_reduce_or:
14424 case Builtin::BI__builtin_reduce_xor:
14425 case Builtin::BI__builtin_reduce_min:
14426 case Builtin::BI__builtin_reduce_max: {
14433 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
14434 switch (BuiltinOp) {
14437 case Builtin::BI__builtin_reduce_add: {
14440 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
14444 case Builtin::BI__builtin_reduce_mul: {
14447 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
14451 case Builtin::BI__builtin_reduce_and: {
14455 case Builtin::BI__builtin_reduce_or: {
14459 case Builtin::BI__builtin_reduce_xor: {
14463 case Builtin::BI__builtin_reduce_min: {
14467 case Builtin::BI__builtin_reduce_max: {
14477 case clang::X86::BI__builtin_ia32_addcarryx_u32:
14478 case clang::X86::BI__builtin_ia32_addcarryx_u64:
14479 case clang::X86::BI__builtin_ia32_subborrow_u32:
14480 case clang::X86::BI__builtin_ia32_subborrow_u64: {
14481 LValue ResultLValue;
14482 APSInt CarryIn, LHS, RHS;
14490 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
14491 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
14493 unsigned BitWidth = LHS.getBitWidth();
14494 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
14497 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
14498 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
14500 APInt Result = ExResult.extractBits(BitWidth, 0);
14501 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
14509 case clang::X86::BI__builtin_ia32_bextr_u32:
14510 case clang::X86::BI__builtin_ia32_bextr_u64:
14511 case clang::X86::BI__builtin_ia32_bextri_u32:
14512 case clang::X86::BI__builtin_ia32_bextri_u64: {
14518 unsigned BitWidth = Val.getBitWidth();
14520 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
14521 Length = Length > BitWidth ? BitWidth : Length;
14524 if (Length == 0 || Shift >= BitWidth)
14528 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
14532 case clang::X86::BI__builtin_ia32_bzhi_si:
14533 case clang::X86::BI__builtin_ia32_bzhi_di: {
14539 unsigned BitWidth = Val.getBitWidth();
14540 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
14541 if (Index < BitWidth)
14542 Val.clearHighBits(BitWidth - Index);
14546 case clang::X86::BI__builtin_ia32_lzcnt_u16:
14547 case clang::X86::BI__builtin_ia32_lzcnt_u32:
14548 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
14552 return Success(Val.countLeadingZeros(),
E);
14555 case clang::X86::BI__builtin_ia32_tzcnt_u16:
14556 case clang::X86::BI__builtin_ia32_tzcnt_u32:
14557 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
14561 return Success(Val.countTrailingZeros(),
E);
14564 case clang::X86::BI__builtin_ia32_pdep_si:
14565 case clang::X86::BI__builtin_ia32_pdep_di: {
14571 unsigned BitWidth = Val.getBitWidth();
14572 APInt Result = APInt::getZero(BitWidth);
14573 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
14575 Result.setBitVal(I, Val[
P++]);
14579 case clang::X86::BI__builtin_ia32_pext_si:
14580 case clang::X86::BI__builtin_ia32_pext_di: {
14586 unsigned BitWidth = Val.getBitWidth();
14587 APInt Result = APInt::getZero(BitWidth);
14588 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I)
14590 Result.setBitVal(
P++, Val[I]);
14599 const LValue &LV) {
14602 if (!LV.getLValueBase())
14607 if (!LV.getLValueDesignator().Invalid &&
14608 !LV.getLValueDesignator().isOnePastTheEnd())
14613 QualType Ty = getType(LV.getLValueBase());
14618 if (LV.getLValueDesignator().Invalid)
14624 return LV.getLValueOffset() == Size;
14634class DataRecursiveIntBinOpEvaluator {
14635 struct EvalResult {
14637 bool Failed =
false;
14639 EvalResult() =
default;
14641 void swap(EvalResult &RHS) {
14643 Failed = RHS.Failed;
14644 RHS.Failed =
false;
14650 EvalResult LHSResult;
14651 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
14654 Job(Job &&) =
default;
14656 void startSpeculativeEval(EvalInfo &Info) {
14657 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
14661 SpeculativeEvaluationRAII SpecEvalRAII;
14666 IntExprEvaluator &IntEval;
14671 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
14672 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
14679 return E->getOpcode() == BO_Comma ||
E->isLogicalOp() ||
14687 EvalResult PrevResult;
14688 while (!Queue.empty())
14689 process(PrevResult);
14691 if (PrevResult.Failed)
return false;
14693 FinalResult.
swap(PrevResult.Val);
14699 return IntEval.Success(
Value,
E, Result);
14702 return IntEval.Success(
Value,
E, Result);
14705 return IntEval.Error(
E);
14708 return IntEval.Error(
E,
D);
14712 return Info.CCEDiag(
E,
D);
14716 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *
E,
14717 bool &SuppressRHSDiags);
14719 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14722 void EvaluateExpr(
const Expr *
E, EvalResult &Result) {
14723 Result.Failed = !
Evaluate(Result.Val, Info,
E);
14728 void process(EvalResult &Result);
14730 void enqueue(
const Expr *
E) {
14732 Queue.resize(Queue.size()+1);
14733 Queue.back().E =
E;
14734 Queue.back().Kind = Job::AnyExprKind;
14740bool DataRecursiveIntBinOpEvaluator::
14742 bool &SuppressRHSDiags) {
14743 if (
E->getOpcode() == BO_Comma) {
14745 if (LHSResult.Failed)
14746 return Info.noteSideEffect();
14750 if (
E->isLogicalOp()) {
14755 if (LHSAsBool == (
E->getOpcode() == BO_LOr)) {
14756 Success(LHSAsBool,
E, LHSResult.Val);
14760 LHSResult.Failed =
true;
14764 if (!Info.noteSideEffect())
14770 SuppressRHSDiags =
true;
14779 if (LHSResult.Failed && !Info.noteFailure())
14790 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
14792 uint64_t Offset64 = Offset.getQuantity();
14793 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
14795 : Offset64 + Index64);
14798bool DataRecursiveIntBinOpEvaluator::
14799 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
14801 if (
E->getOpcode() == BO_Comma) {
14802 if (RHSResult.Failed)
14804 Result = RHSResult.Val;
14808 if (
E->isLogicalOp()) {
14809 bool lhsResult, rhsResult;
14815 if (
E->getOpcode() == BO_LOr)
14816 return Success(lhsResult || rhsResult,
E, Result);
14818 return Success(lhsResult && rhsResult,
E, Result);
14824 if (rhsResult == (
E->getOpcode() == BO_LOr))
14825 return Success(rhsResult,
E, Result);
14835 if (LHSResult.Failed || RHSResult.Failed)
14838 const APValue &LHSVal = LHSResult.Val;
14839 const APValue &RHSVal = RHSResult.Val;
14849 if (
E->getOpcode() == BO_Add &&
14863 if (!LHSExpr || !RHSExpr)
14865 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
14866 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
14867 if (!LHSAddrExpr || !RHSAddrExpr)
14873 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
14892void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
14893 Job &job = Queue.back();
14895 switch (job.Kind) {
14896 case Job::AnyExprKind: {
14897 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
14898 if (shouldEnqueue(Bop)) {
14899 job.Kind = Job::BinOpKind;
14900 enqueue(Bop->getLHS());
14905 EvaluateExpr(job.E, Result);
14910 case Job::BinOpKind: {
14912 bool SuppressRHSDiags =
false;
14913 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
14917 if (SuppressRHSDiags)
14918 job.startSpeculativeEval(Info);
14919 job.LHSResult.swap(Result);
14920 job.Kind = Job::BinOpVisitedLHSKind;
14925 case Job::BinOpVisitedLHSKind: {
14929 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
14935 llvm_unreachable(
"Invalid Job::Kind!");
14939enum class CmpResult {
14948template <
class SuccessCB,
class AfterCB>
14951 SuccessCB &&
Success, AfterCB &&DoAfter) {
14953 assert(
E->isComparisonOp() &&
"expected comparison operator");
14954 assert((
E->getOpcode() == BO_Cmp ||
14956 "unsupported binary expression evaluation");
14957 auto Error = [&](
const Expr *
E) {
14958 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
14962 bool IsRelational =
E->isRelationalOp() ||
E->getOpcode() == BO_Cmp;
14963 bool IsEquality =
E->isEqualityOp();
14972 if (!LHSOK && !Info.noteFailure())
14977 return Success(CmpResult::Less,
E);
14979 return Success(CmpResult::Greater,
E);
14980 return Success(CmpResult::Equal,
E);
14984 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
14985 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
14988 if (!LHSOK && !Info.noteFailure())
14993 return Success(CmpResult::Less,
E);
14995 return Success(CmpResult::Greater,
E);
14996 return Success(CmpResult::Equal,
E);
15000 ComplexValue LHS, RHS;
15002 if (
E->isAssignmentOp()) {
15009 LHS.makeComplexFloat();
15010 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
15015 if (!LHSOK && !Info.noteFailure())
15021 RHS.makeComplexFloat();
15022 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
15026 if (LHS.isComplexFloat()) {
15027 APFloat::cmpResult CR_r =
15028 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
15029 APFloat::cmpResult CR_i =
15030 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
15031 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
15032 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
15034 assert(IsEquality &&
"invalid complex comparison");
15035 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
15036 LHS.getComplexIntImag() == RHS.getComplexIntImag();
15037 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal,
E);
15043 APFloat RHS(0.0), LHS(0.0);
15046 if (!LHSOK && !Info.noteFailure())
15052 assert(
E->isComparisonOp() &&
"Invalid binary operator!");
15053 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
15054 if (!Info.InConstantContext &&
15055 APFloatCmpResult == APFloat::cmpUnordered &&
15058 Info.FFDiag(
E, diag::note_constexpr_float_arithmetic_strict);
15061 auto GetCmpRes = [&]() {
15062 switch (APFloatCmpResult) {
15063 case APFloat::cmpEqual:
15064 return CmpResult::Equal;
15065 case APFloat::cmpLessThan:
15066 return CmpResult::Less;
15067 case APFloat::cmpGreaterThan:
15068 return CmpResult::Greater;
15069 case APFloat::cmpUnordered:
15070 return CmpResult::Unordered;
15072 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
15078 LValue LHSValue, RHSValue;
15081 if (!LHSOK && !Info.noteFailure())
15092 if (Info.checkingPotentialConstantExpression() &&
15093 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15095 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
15096 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
15097 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
15098 Info.FFDiag(
E, DiagID)
15105 return DiagComparison(
15106 diag::note_constexpr_pointer_comparison_unspecified);
15112 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
15113 (!RHSValue.Base && !RHSValue.Offset.isZero()))
15114 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
15128 return DiagComparison(diag::note_constexpr_literal_comparison);
15130 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
15135 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
15139 if (LHSValue.Base && LHSValue.Offset.isZero() &&
15141 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15143 if (RHSValue.Base && RHSValue.Offset.isZero() &&
15145 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
15151 return DiagComparison(
15152 diag::note_constexpr_pointer_comparison_zero_sized);
15153 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
15154 return DiagComparison(
15155 diag::note_constexpr_pointer_comparison_unspecified);
15157 return Success(CmpResult::Unequal,
E);
15160 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15161 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15163 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15164 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15174 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
15175 bool WasArrayIndex;
15177 LHSValue.Base.isNull() ?
QualType()
15179 LHSDesignator, RHSDesignator, WasArrayIndex);
15186 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
15187 Mismatch < RHSDesignator.Entries.size()) {
15188 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
15189 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
15191 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_classes);
15193 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
15194 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
15197 Info.CCEDiag(
E, diag::note_constexpr_pointer_comparison_base_field)
15198 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
15203 diag::note_constexpr_pointer_comparison_differing_access)
15211 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
15214 assert(PtrSize <= 64 &&
"Unexpected pointer width");
15215 uint64_t Mask = ~0ULL >> (64 - PtrSize);
15216 CompareLHS &= Mask;
15217 CompareRHS &= Mask;
15222 if (!LHSValue.Base.isNull() && IsRelational) {
15226 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
15227 uint64_t OffsetLimit = Size.getQuantity();
15228 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
15232 if (CompareLHS < CompareRHS)
15233 return Success(CmpResult::Less,
E);
15234 if (CompareLHS > CompareRHS)
15235 return Success(CmpResult::Greater,
E);
15236 return Success(CmpResult::Equal,
E);
15240 assert(IsEquality &&
"unexpected member pointer operation");
15243 MemberPtr LHSValue, RHSValue;
15246 if (!LHSOK && !Info.noteFailure())
15254 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
15255 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
15256 << LHSValue.getDecl();
15259 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
15260 Info.FFDiag(
E, diag::note_constexpr_mem_pointer_weak_comparison)
15261 << RHSValue.getDecl();
15268 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
15269 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
15270 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
15275 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
15276 if (MD->isVirtual())
15277 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15278 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
15279 if (MD->isVirtual())
15280 Info.CCEDiag(
E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
15286 bool Equal = LHSValue == RHSValue;
15287 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal,
E);
15291 assert(
E->isComparisonOp() &&
"unexpected nullptr operation");
15292 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
15300 return Success(CmpResult::Equal,
E);
15313 case CmpResult::Unequal:
15314 llvm_unreachable(
"should never produce Unequal for three-way comparison");
15315 case CmpResult::Less:
15316 CCR = ComparisonCategoryResult::Less;
15318 case CmpResult::Equal:
15319 CCR = ComparisonCategoryResult::Equal;
15321 case CmpResult::Greater:
15322 CCR = ComparisonCategoryResult::Greater;
15324 case CmpResult::Unordered:
15325 CCR = ComparisonCategoryResult::Unordered;
15339 ConstantExprKind::Normal);
15342 return ExprEvaluatorBaseTy::VisitBinCmp(
E);
15346bool RecordExprEvaluator::VisitCXXParenListInitExpr(
15348 return VisitCXXParenListOrInitListExpr(
E,
E->getInitExprs());
15354 if (
E->isAssignmentOp()) {
15356 if (!Info.noteFailure())
15360 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(
E))
15361 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(
E);
15365 "DataRecursiveIntBinOpEvaluator should have handled integral types");
15367 if (
E->isComparisonOp()) {
15371 assert((CR != CmpResult::Unequal ||
E->isEqualityOp()) &&
15372 "should only produce Unequal for equality comparisons");
15373 bool IsEqual = CR == CmpResult::Equal,
15374 IsLess = CR == CmpResult::Less,
15375 IsGreater = CR == CmpResult::Greater;
15376 auto Op =
E->getOpcode();
15379 llvm_unreachable(
"unsupported binary operator");
15382 return Success(IsEqual == (Op == BO_EQ),
E);
15388 return Success(IsEqual || IsLess,
E);
15390 return Success(IsEqual || IsGreater,
E);
15394 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15402 E->getOpcode() == BO_Sub) {
15403 LValue LHSValue, RHSValue;
15406 if (!LHSOK && !Info.noteFailure())
15415 if (Info.checkingPotentialConstantExpression() &&
15416 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
15419 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
15420 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
15422 auto DiagArith = [&](
unsigned DiagID) {
15423 std::string LHS = LHSValue.toString(Info.Ctx,
E->getLHS()->
getType());
15424 std::string RHS = RHSValue.toString(Info.Ctx,
E->getRHS()->
getType());
15425 Info.FFDiag(
E, DiagID) << LHS << RHS;
15426 if (LHSExpr && LHSExpr == RHSExpr)
15428 diag::note_constexpr_repeated_literal_eval)
15433 if (!LHSExpr || !RHSExpr)
15434 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
15437 return DiagArith(diag::note_constexpr_literal_arith);
15439 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
15440 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
15441 if (!LHSAddrExpr || !RHSAddrExpr)
15449 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
15450 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
15452 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
15453 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
15459 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
15462 Info.CCEDiag(
E, diag::note_constexpr_pointer_subtraction_not_same_array);
15474 if (ElementSize.
isZero()) {
15475 Info.FFDiag(
E, diag::note_constexpr_pointer_subtraction_zero_size)
15492 APSInt TrueResult = (LHS - RHS) / ElemSize;
15493 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(
E->
getType()));
15495 if (Result.extend(65) != TrueResult &&
15501 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
15506bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
15508 switch(
E->getKind()) {
15509 case UETT_PreferredAlignOf:
15510 case UETT_AlignOf: {
15511 if (
E->isArgumentType())
15519 case UETT_PtrAuthTypeDiscriminator: {
15520 if (
E->getArgumentType()->isDependentType())
15523 Info.Ctx.getPointerAuthTypeDiscriminator(
E->getArgumentType()),
E);
15525 case UETT_VecStep: {
15541 case UETT_DataSizeOf:
15542 case UETT_SizeOf: {
15543 QualType SrcTy =
E->getTypeOfArgument();
15551 E->getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
15552 : SizeOfType::SizeOf)) {
15557 case UETT_OpenMPRequiredSimdAlign:
15558 assert(
E->isArgumentType());
15560 Info.Ctx.toCharUnitsFromBits(
15561 Info.Ctx.getOpenMPDefaultSimdAlign(
E->getArgumentType()))
15564 case UETT_VectorElements: {
15572 if (Info.InConstantContext)
15573 Info.CCEDiag(
E, diag::note_constexpr_non_const_vectorelements)
15578 case UETT_CountOf: {
15584 if (
const auto *CAT =
15594 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
15596 if (VAT->getElementType()->isArrayType()) {
15599 if (!VAT->getSizeExpr()) {
15604 std::optional<APSInt> Res =
15605 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
15610 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
15611 Res->getZExtValue()};
15623 llvm_unreachable(
"unknown expr/type trait");
15626bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
15632 for (
unsigned i = 0; i != n; ++i) {
15640 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
15644 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
15645 Result += IdxResult.getSExtValue() * ElementSize;
15657 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
15664 llvm_unreachable(
"dependent __builtin_offsetof");
15679 CurrentType = BaseSpec->
getType();
15693bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
15694 switch (
E->getOpcode()) {
15702 return Visit(
E->getSubExpr());
15705 return Visit(
E->getSubExpr());
15707 if (!Visit(
E->getSubExpr()))
15709 if (!Result.isInt())
return Error(
E);
15711 if (
Value.isSigned() &&
Value.isMinSignedValue() &&
E->canOverflow()) {
15712 if (Info.checkingForUndefinedBehavior())
15713 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
15714 diag::warn_integer_constant_overflow)
15726 if (!Visit(
E->getSubExpr()))
15728 if (!Result.isInt())
return Error(
E);
15729 return Success(~Result.getInt(),
E);
15742bool IntExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
15743 const Expr *SubExpr =
E->getSubExpr();
15747 switch (
E->getCastKind()) {
15748 case CK_BaseToDerived:
15749 case CK_DerivedToBase:
15750 case CK_UncheckedDerivedToBase:
15753 case CK_ArrayToPointerDecay:
15754 case CK_FunctionToPointerDecay:
15755 case CK_NullToPointer:
15756 case CK_NullToMemberPointer:
15757 case CK_BaseToDerivedMemberPointer:
15758 case CK_DerivedToBaseMemberPointer:
15759 case CK_ReinterpretMemberPointer:
15760 case CK_ConstructorConversion:
15761 case CK_IntegralToPointer:
15763 case CK_VectorSplat:
15764 case CK_IntegralToFloating:
15765 case CK_FloatingCast:
15766 case CK_CPointerToObjCPointerCast:
15767 case CK_BlockPointerToObjCPointerCast:
15768 case CK_AnyPointerToBlockPointerCast:
15769 case CK_ObjCObjectLValueCast:
15770 case CK_FloatingRealToComplex:
15771 case CK_FloatingComplexToReal:
15772 case CK_FloatingComplexCast:
15773 case CK_FloatingComplexToIntegralComplex:
15774 case CK_IntegralRealToComplex:
15775 case CK_IntegralComplexCast:
15776 case CK_IntegralComplexToFloatingComplex:
15777 case CK_BuiltinFnToFnPtr:
15778 case CK_ZeroToOCLOpaqueType:
15779 case CK_NonAtomicToAtomic:
15780 case CK_AddressSpaceConversion:
15781 case CK_IntToOCLSampler:
15782 case CK_FloatingToFixedPoint:
15783 case CK_FixedPointToFloating:
15784 case CK_FixedPointCast:
15785 case CK_IntegralToFixedPoint:
15786 case CK_MatrixCast:
15787 case CK_HLSLAggregateSplatCast:
15788 llvm_unreachable(
"invalid cast kind for integral value");
15792 case CK_LValueBitCast:
15793 case CK_ARCProduceObject:
15794 case CK_ARCConsumeObject:
15795 case CK_ARCReclaimReturnedObject:
15796 case CK_ARCExtendBlockObject:
15797 case CK_CopyAndAutoreleaseBlockObject:
15800 case CK_UserDefinedConversion:
15801 case CK_LValueToRValue:
15802 case CK_AtomicToNonAtomic:
15804 case CK_LValueToRValueBitCast:
15805 case CK_HLSLArrayRValue:
15806 case CK_HLSLElementwiseCast:
15807 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
15809 case CK_MemberPointerToBoolean:
15810 case CK_PointerToBoolean:
15811 case CK_IntegralToBoolean:
15812 case CK_FloatingToBoolean:
15813 case CK_BooleanToSignedIntegral:
15814 case CK_FloatingComplexToBoolean:
15815 case CK_IntegralComplexToBoolean: {
15820 if (BoolResult &&
E->getCastKind() == CK_BooleanToSignedIntegral)
15825 case CK_FixedPointToIntegral: {
15826 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
15830 llvm::APSInt Result = Src.convertToInt(
15831 Info.Ctx.getIntWidth(DestType),
15838 case CK_FixedPointToBoolean: {
15841 if (!
Evaluate(Val, Info, SubExpr))
15846 case CK_IntegralCast: {
15847 if (!Visit(SubExpr))
15850 if (!Result.isInt()) {
15856 if (Result.isAddrLabelDiff())
15857 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
15859 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
15862 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
15874 if (!ED->isFixed()) {
15878 ED->getValueRange(
Max,
Min);
15881 if (ED->getNumNegativeBits() &&
15882 (
Max.slt(Result.getInt().getSExtValue()) ||
15883 Min.sgt(Result.getInt().getSExtValue())))
15884 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15885 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
15886 <<
Max.getSExtValue() << ED;
15887 else if (!ED->getNumNegativeBits() &&
15888 Max.ult(Result.getInt().getZExtValue()))
15889 Info.CCEDiag(
E, diag::note_constexpr_unscoped_enum_out_of_range)
15890 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
15891 <<
Max.getZExtValue() << ED;
15896 Result.getInt()),
E);
15899 case CK_PointerToIntegral: {
15900 CCEDiag(
E, diag::note_constexpr_invalid_cast)
15901 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
15908 if (LV.getLValueBase()) {
15913 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
15916 LV.Designator.setInvalid();
15917 LV.moveInto(Result);
15924 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
15925 llvm_unreachable(
"Can't cast this!");
15930 case CK_IntegralComplexToReal: {
15934 return Success(
C.getComplexIntReal(),
E);
15937 case CK_FloatingToIntegral: {
15947 case CK_HLSLVectorTruncation: {
15955 llvm_unreachable(
"unknown cast resulting in integral value");
15963 if (!LV.isComplexInt())
15965 return Success(LV.getComplexIntReal(),
E);
15968 return Visit(
E->getSubExpr());
15976 if (!LV.isComplexInt())
15978 return Success(LV.getComplexIntImag(),
E);
15981 VisitIgnoredValue(
E->getSubExpr());
15993bool IntExprEvaluator::VisitConceptSpecializationExpr(
15998bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *
E) {
16002bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16003 switch (
E->getOpcode()) {
16009 return Visit(
E->getSubExpr());
16011 if (!Visit(
E->getSubExpr()))
return false;
16012 if (!Result.isFixedPoint())
16015 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
16029bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
16030 const Expr *SubExpr =
E->getSubExpr();
16033 "Expected destination type to be a fixed point type");
16034 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
16036 switch (
E->getCastKind()) {
16037 case CK_FixedPointCast: {
16038 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
16042 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
16044 if (Info.checkingForUndefinedBehavior())
16045 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
16046 diag::warn_fixedpoint_constant_overflow)
16047 << Result.toString() <<
E->
getType();
16053 case CK_IntegralToFixedPoint: {
16059 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
16060 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
16063 if (Info.checkingForUndefinedBehavior())
16064 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
16065 diag::warn_fixedpoint_constant_overflow)
16066 << IntResult.toString() <<
E->
getType();
16073 case CK_FloatingToFixedPoint: {
16079 APFixedPoint Result = APFixedPoint::getFromFloatValue(
16080 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
16083 if (Info.checkingForUndefinedBehavior())
16084 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
16085 diag::warn_fixedpoint_constant_overflow)
16086 << Result.toString() <<
E->
getType();
16094 case CK_LValueToRValue:
16095 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16101bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
16102 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
16103 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
16105 const Expr *LHS =
E->getLHS();
16106 const Expr *RHS =
E->getRHS();
16108 Info.Ctx.getFixedPointSemantics(
E->
getType());
16110 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
16113 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
16117 bool OpOverflow =
false, ConversionOverflow =
false;
16118 APFixedPoint Result(LHSFX.getSemantics());
16119 switch (
E->getOpcode()) {
16121 Result = LHSFX.
add(RHSFX, &OpOverflow)
16122 .convert(ResultFXSema, &ConversionOverflow);
16126 Result = LHSFX.sub(RHSFX, &OpOverflow)
16127 .convert(ResultFXSema, &ConversionOverflow);
16131 Result = LHSFX.mul(RHSFX, &OpOverflow)
16132 .convert(ResultFXSema, &ConversionOverflow);
16136 if (RHSFX.getValue() == 0) {
16137 Info.FFDiag(
E, diag::note_expr_divide_by_zero);
16140 Result = LHSFX.div(RHSFX, &OpOverflow)
16141 .convert(ResultFXSema, &ConversionOverflow);
16147 llvm::APSInt RHSVal = RHSFX.getValue();
16150 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
16151 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
16155 if (RHSVal.isNegative())
16156 Info.CCEDiag(
E, diag::note_constexpr_negative_shift) << RHSVal;
16157 else if (Amt != RHSVal)
16158 Info.CCEDiag(
E, diag::note_constexpr_large_shift)
16159 << RHSVal <<
E->
getType() << ShiftBW;
16161 if (
E->getOpcode() == BO_Shl)
16162 Result = LHSFX.shl(Amt, &OpOverflow);
16164 Result = LHSFX.shr(Amt, &OpOverflow);
16170 if (OpOverflow || ConversionOverflow) {
16171 if (Info.checkingForUndefinedBehavior())
16172 Info.Ctx.getDiagnostics().Report(
E->
getExprLoc(),
16173 diag::warn_fixedpoint_constant_overflow)
16174 << Result.toString() <<
E->
getType();
16186class FloatExprEvaluator
16187 :
public ExprEvaluatorBase<FloatExprEvaluator> {
16190 FloatExprEvaluator(EvalInfo &info, APFloat &result)
16191 : ExprEvaluatorBaseTy(info), Result(result) {}
16194 Result =
V.getFloat();
16198 bool ZeroInitialization(
const Expr *
E) {
16199 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
16220 return FloatExprEvaluator(Info, Result).Visit(
E);
16227 llvm::APFloat &Result) {
16229 if (!S)
return false;
16236 if (S->getString().empty())
16237 fill = llvm::APInt(32, 0);
16238 else if (S->getString().getAsInteger(0, fill))
16243 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16245 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16253 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
16255 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
16261bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
16262 if (!IsConstantEvaluatedBuiltinCall(
E))
16263 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
16265 switch (
E->getBuiltinCallee()) {
16269 case Builtin::BI__builtin_huge_val:
16270 case Builtin::BI__builtin_huge_valf:
16271 case Builtin::BI__builtin_huge_vall:
16272 case Builtin::BI__builtin_huge_valf16:
16273 case Builtin::BI__builtin_huge_valf128:
16274 case Builtin::BI__builtin_inf:
16275 case Builtin::BI__builtin_inff:
16276 case Builtin::BI__builtin_infl:
16277 case Builtin::BI__builtin_inff16:
16278 case Builtin::BI__builtin_inff128: {
16279 const llvm::fltSemantics &Sem =
16280 Info.Ctx.getFloatTypeSemantics(
E->
getType());
16281 Result = llvm::APFloat::getInf(Sem);
16285 case Builtin::BI__builtin_nans:
16286 case Builtin::BI__builtin_nansf:
16287 case Builtin::BI__builtin_nansl:
16288 case Builtin::BI__builtin_nansf16:
16289 case Builtin::BI__builtin_nansf128:
16295 case Builtin::BI__builtin_nan:
16296 case Builtin::BI__builtin_nanf:
16297 case Builtin::BI__builtin_nanl:
16298 case Builtin::BI__builtin_nanf16:
16299 case Builtin::BI__builtin_nanf128:
16307 case Builtin::BI__builtin_elementwise_abs:
16308 case Builtin::BI__builtin_fabs:
16309 case Builtin::BI__builtin_fabsf:
16310 case Builtin::BI__builtin_fabsl:
16311 case Builtin::BI__builtin_fabsf128:
16320 if (Result.isNegative())
16321 Result.changeSign();
16324 case Builtin::BI__arithmetic_fence:
16331 case Builtin::BI__builtin_copysign:
16332 case Builtin::BI__builtin_copysignf:
16333 case Builtin::BI__builtin_copysignl:
16334 case Builtin::BI__builtin_copysignf128: {
16339 Result.copySign(RHS);
16343 case Builtin::BI__builtin_fmax:
16344 case Builtin::BI__builtin_fmaxf:
16345 case Builtin::BI__builtin_fmaxl:
16346 case Builtin::BI__builtin_fmaxf16:
16347 case Builtin::BI__builtin_fmaxf128: {
16352 Result = maxnum(Result, RHS);
16356 case Builtin::BI__builtin_fmin:
16357 case Builtin::BI__builtin_fminf:
16358 case Builtin::BI__builtin_fminl:
16359 case Builtin::BI__builtin_fminf16:
16360 case Builtin::BI__builtin_fminf128: {
16365 Result = minnum(Result, RHS);
16369 case Builtin::BI__builtin_fmaximum_num:
16370 case Builtin::BI__builtin_fmaximum_numf:
16371 case Builtin::BI__builtin_fmaximum_numl:
16372 case Builtin::BI__builtin_fmaximum_numf16:
16373 case Builtin::BI__builtin_fmaximum_numf128: {
16378 Result = maximumnum(Result, RHS);
16382 case Builtin::BI__builtin_fminimum_num:
16383 case Builtin::BI__builtin_fminimum_numf:
16384 case Builtin::BI__builtin_fminimum_numl:
16385 case Builtin::BI__builtin_fminimum_numf16:
16386 case Builtin::BI__builtin_fminimum_numf128: {
16391 Result = minimumnum(Result, RHS);
16395 case Builtin::BI__builtin_elementwise_fma: {
16400 APFloat SourceY(0.), SourceZ(0.);
16406 (void)Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
16412bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *
E) {
16417 Result = CV.FloatReal;
16421 return Visit(
E->getSubExpr());
16424bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *
E) {
16429 Result = CV.FloatImag;
16433 VisitIgnoredValue(
E->getSubExpr());
16434 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(
E->
getType());
16435 Result = llvm::APFloat::getZero(Sem);
16439bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
16440 switch (
E->getOpcode()) {
16441 default:
return Error(
E);
16450 Result.changeSign();
16455bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
16456 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
16457 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
16461 if (!LHSOK && !Info.noteFailure())
16468 Result =
E->getValue();
16472bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
16473 const Expr* SubExpr =
E->getSubExpr();
16475 switch (
E->getCastKind()) {
16477 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16479 case CK_IntegralToFloating: {
16482 Info.Ctx.getLangOpts());
16488 case CK_FixedPointToFloating: {
16489 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
16493 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(
E->
getType()));
16497 case CK_FloatingCast: {
16498 if (!Visit(SubExpr))
16504 case CK_FloatingComplexToReal: {
16508 Result =
V.getComplexFloatReal();
16511 case CK_HLSLVectorTruncation: {
16525class ComplexExprEvaluator
16526 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
16527 ComplexValue &Result;
16530 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
16531 : ExprEvaluatorBaseTy(info), Result(Result) {}
16538 bool ZeroInitialization(
const Expr *
E);
16557 return ComplexExprEvaluator(Info, Result).Visit(
E);
16560bool ComplexExprEvaluator::ZeroInitialization(
const Expr *
E) {
16563 Result.makeComplexFloat();
16564 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
16565 Result.FloatReal =
Zero;
16566 Result.FloatImag =
Zero;
16568 Result.makeComplexInt();
16569 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
16570 Result.IntReal =
Zero;
16571 Result.IntImag =
Zero;
16577 const Expr* SubExpr =
E->getSubExpr();
16580 Result.makeComplexFloat();
16581 APFloat &Imag = Result.FloatImag;
16585 Result.FloatReal =
APFloat(Imag.getSemantics());
16589 "Unexpected imaginary literal.");
16591 Result.makeComplexInt();
16592 APSInt &Imag = Result.IntImag;
16596 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
16601bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *
E) {
16603 switch (
E->getCastKind()) {
16605 case CK_BaseToDerived:
16606 case CK_DerivedToBase:
16607 case CK_UncheckedDerivedToBase:
16610 case CK_ArrayToPointerDecay:
16611 case CK_FunctionToPointerDecay:
16612 case CK_NullToPointer:
16613 case CK_NullToMemberPointer:
16614 case CK_BaseToDerivedMemberPointer:
16615 case CK_DerivedToBaseMemberPointer:
16616 case CK_MemberPointerToBoolean:
16617 case CK_ReinterpretMemberPointer:
16618 case CK_ConstructorConversion:
16619 case CK_IntegralToPointer:
16620 case CK_PointerToIntegral:
16621 case CK_PointerToBoolean:
16623 case CK_VectorSplat:
16624 case CK_IntegralCast:
16625 case CK_BooleanToSignedIntegral:
16626 case CK_IntegralToBoolean:
16627 case CK_IntegralToFloating:
16628 case CK_FloatingToIntegral:
16629 case CK_FloatingToBoolean:
16630 case CK_FloatingCast:
16631 case CK_CPointerToObjCPointerCast:
16632 case CK_BlockPointerToObjCPointerCast:
16633 case CK_AnyPointerToBlockPointerCast:
16634 case CK_ObjCObjectLValueCast:
16635 case CK_FloatingComplexToReal:
16636 case CK_FloatingComplexToBoolean:
16637 case CK_IntegralComplexToReal:
16638 case CK_IntegralComplexToBoolean:
16639 case CK_ARCProduceObject:
16640 case CK_ARCConsumeObject:
16641 case CK_ARCReclaimReturnedObject:
16642 case CK_ARCExtendBlockObject:
16643 case CK_CopyAndAutoreleaseBlockObject:
16644 case CK_BuiltinFnToFnPtr:
16645 case CK_ZeroToOCLOpaqueType:
16646 case CK_NonAtomicToAtomic:
16647 case CK_AddressSpaceConversion:
16648 case CK_IntToOCLSampler:
16649 case CK_FloatingToFixedPoint:
16650 case CK_FixedPointToFloating:
16651 case CK_FixedPointCast:
16652 case CK_FixedPointToBoolean:
16653 case CK_FixedPointToIntegral:
16654 case CK_IntegralToFixedPoint:
16655 case CK_MatrixCast:
16656 case CK_HLSLVectorTruncation:
16657 case CK_HLSLElementwiseCast:
16658 case CK_HLSLAggregateSplatCast:
16659 llvm_unreachable(
"invalid cast kind for complex value");
16661 case CK_LValueToRValue:
16662 case CK_AtomicToNonAtomic:
16664 case CK_LValueToRValueBitCast:
16665 case CK_HLSLArrayRValue:
16666 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
16669 case CK_LValueBitCast:
16670 case CK_UserDefinedConversion:
16673 case CK_FloatingRealToComplex: {
16674 APFloat &Real = Result.FloatReal;
16678 Result.makeComplexFloat();
16679 Result.FloatImag =
APFloat(Real.getSemantics());
16683 case CK_FloatingComplexCast: {
16684 if (!Visit(
E->getSubExpr()))
16695 case CK_FloatingComplexToIntegralComplex: {
16696 if (!Visit(
E->getSubExpr()))
16702 Result.makeComplexInt();
16704 To, Result.IntReal) &&
16706 To, Result.IntImag);
16709 case CK_IntegralRealToComplex: {
16710 APSInt &Real = Result.IntReal;
16714 Result.makeComplexInt();
16715 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
16719 case CK_IntegralComplexCast: {
16720 if (!Visit(
E->getSubExpr()))
16732 case CK_IntegralComplexToFloatingComplex: {
16733 if (!Visit(
E->getSubExpr()))
16737 Info.Ctx.getLangOpts());
16741 Result.makeComplexFloat();
16743 To, Result.FloatReal) &&
16745 To, Result.FloatImag);
16749 llvm_unreachable(
"unknown cast resulting in complex value");
16753 APFloat &ResR, APFloat &ResI) {
16759 APFloat AC = A *
C;
16760 APFloat BD = B *
D;
16761 APFloat AD = A *
D;
16762 APFloat BC = B *
C;
16765 if (ResR.isNaN() && ResI.isNaN()) {
16766 bool Recalc =
false;
16767 if (A.isInfinity() || B.isInfinity()) {
16768 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16770 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16773 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16775 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16778 if (
C.isInfinity() ||
D.isInfinity()) {
16779 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16781 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16784 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16786 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16789 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
16790 BC.isInfinity())) {
16792 A = APFloat::copySign(APFloat(A.getSemantics()), A);
16794 B = APFloat::copySign(APFloat(B.getSemantics()), B);
16796 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
16798 D = APFloat::copySign(APFloat(
D.getSemantics()),
D);
16802 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B *
D);
16803 ResI = APFloat::getInf(A.getSemantics()) * (A *
D + B *
C);
16809 APFloat &ResR, APFloat &ResI) {
16816 APFloat MaxCD = maxnum(
abs(
C),
abs(
D));
16817 if (MaxCD.isFinite()) {
16818 DenomLogB =
ilogb(MaxCD);
16819 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
16820 D =
scalbn(
D, -DenomLogB, APFloat::rmNearestTiesToEven);
16822 APFloat Denom =
C *
C +
D *
D;
16824 scalbn((A *
C + B *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16826 scalbn((B *
C - A *
D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
16827 if (ResR.isNaN() && ResI.isNaN()) {
16828 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
16829 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
16830 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
16831 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
16833 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
16835 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
16837 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B *
D);
16838 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A *
D);
16839 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
16840 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
16842 D = APFloat::copySign(APFloat(
D.getSemantics(),
D.isInfinity() ? 1 : 0),
16844 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B *
D);
16845 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A *
D);
16850bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *
E) {
16851 if (
E->isPtrMemOp() ||
E->isAssignmentOp() ||
E->getOpcode() == BO_Comma)
16852 return ExprEvaluatorBaseTy::VisitBinaryOperator(
E);
16856 bool LHSReal =
false, RHSReal =
false;
16861 APFloat &Real = Result.FloatReal;
16864 Result.makeComplexFloat();
16865 Result.FloatImag =
APFloat(Real.getSemantics());
16868 LHSOK = Visit(
E->getLHS());
16870 if (!LHSOK && !Info.noteFailure())
16876 APFloat &Real = RHS.FloatReal;
16879 RHS.makeComplexFloat();
16880 RHS.FloatImag =
APFloat(Real.getSemantics());
16884 assert(!(LHSReal && RHSReal) &&
16885 "Cannot have both operands of a complex operation be real.");
16886 switch (
E->getOpcode()) {
16887 default:
return Error(
E);
16889 if (Result.isComplexFloat()) {
16890 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
16891 APFloat::rmNearestTiesToEven);
16893 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16895 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
16896 APFloat::rmNearestTiesToEven);
16898 Result.getComplexIntReal() += RHS.getComplexIntReal();
16899 Result.getComplexIntImag() += RHS.getComplexIntImag();
16903 if (Result.isComplexFloat()) {
16904 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
16905 APFloat::rmNearestTiesToEven);
16907 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
16908 Result.getComplexFloatImag().changeSign();
16909 }
else if (!RHSReal) {
16910 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
16911 APFloat::rmNearestTiesToEven);
16914 Result.getComplexIntReal() -= RHS.getComplexIntReal();
16915 Result.getComplexIntImag() -= RHS.getComplexIntImag();
16919 if (Result.isComplexFloat()) {
16924 ComplexValue LHS = Result;
16925 APFloat &A = LHS.getComplexFloatReal();
16926 APFloat &B = LHS.getComplexFloatImag();
16927 APFloat &
C = RHS.getComplexFloatReal();
16928 APFloat &
D = RHS.getComplexFloatImag();
16929 APFloat &ResR = Result.getComplexFloatReal();
16930 APFloat &ResI = Result.getComplexFloatImag();
16932 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
16940 }
else if (RHSReal) {
16952 ComplexValue LHS = Result;
16953 Result.getComplexIntReal() =
16954 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
16955 LHS.getComplexIntImag() * RHS.getComplexIntImag());
16956 Result.getComplexIntImag() =
16957 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
16958 LHS.getComplexIntImag() * RHS.getComplexIntReal());
16962 if (Result.isComplexFloat()) {
16967 ComplexValue LHS = Result;
16968 APFloat &A = LHS.getComplexFloatReal();
16969 APFloat &B = LHS.getComplexFloatImag();
16970 APFloat &
C = RHS.getComplexFloatReal();
16971 APFloat &
D = RHS.getComplexFloatImag();
16972 APFloat &ResR = Result.getComplexFloatReal();
16973 APFloat &ResI = Result.getComplexFloatImag();
16985 B = APFloat::getZero(A.getSemantics());
16990 ComplexValue LHS = Result;
16991 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
16992 RHS.getComplexIntImag() * RHS.getComplexIntImag();
16994 return Error(
E, diag::note_expr_divide_by_zero);
16996 Result.getComplexIntReal() =
16997 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
16998 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
16999 Result.getComplexIntImag() =
17000 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
17001 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
17009bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *
E) {
17011 if (!Visit(
E->getSubExpr()))
17014 switch (
E->getOpcode()) {
17023 if (Result.isComplexFloat()) {
17024 Result.getComplexFloatReal().changeSign();
17025 Result.getComplexFloatImag().changeSign();
17028 Result.getComplexIntReal() = -Result.getComplexIntReal();
17029 Result.getComplexIntImag() = -Result.getComplexIntImag();
17033 if (Result.isComplexFloat())
17034 Result.getComplexFloatImag().changeSign();
17036 Result.getComplexIntImag() = -Result.getComplexIntImag();
17041bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *
E) {
17042 if (
E->getNumInits() == 2) {
17044 Result.makeComplexFloat();
17050 Result.makeComplexInt();
17058 return ExprEvaluatorBaseTy::VisitInitListExpr(
E);
17061bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *
E) {
17062 if (!IsConstantEvaluatedBuiltinCall(
E))
17063 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
17065 switch (
E->getBuiltinCallee()) {
17066 case Builtin::BI__builtin_complex:
17067 Result.makeComplexFloat();
17085class AtomicExprEvaluator :
17086 public ExprEvaluatorBase<AtomicExprEvaluator> {
17087 const LValue *
This;
17090 AtomicExprEvaluator(EvalInfo &Info,
const LValue *
This,
APValue &Result)
17091 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
17098 bool ZeroInitialization(
const Expr *
E) {
17107 bool VisitCastExpr(
const CastExpr *
E) {
17108 switch (
E->getCastKind()) {
17110 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
17111 case CK_NullToPointer:
17112 VisitIgnoredValue(
E->getSubExpr());
17113 return ZeroInitialization(
E);
17114 case CK_NonAtomicToAtomic:
17116 :
Evaluate(Result, Info,
E->getSubExpr());
17126 return AtomicExprEvaluator(Info,
This, Result).Visit(
E);
17135class VoidExprEvaluator
17136 :
public ExprEvaluatorBase<VoidExprEvaluator> {
17138 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
17142 bool ZeroInitialization(
const Expr *
E) {
return true; }
17144 bool VisitCastExpr(
const CastExpr *
E) {
17145 switch (
E->getCastKind()) {
17147 return ExprEvaluatorBaseTy::VisitCastExpr(
E);
17149 VisitIgnoredValue(
E->getSubExpr());
17154 bool VisitCallExpr(
const CallExpr *
E) {
17155 if (!IsConstantEvaluatedBuiltinCall(
E))
17156 return ExprEvaluatorBaseTy::VisitCallExpr(
E);
17158 switch (
E->getBuiltinCallee()) {
17159 case Builtin::BI__assume:
17160 case Builtin::BI__builtin_assume:
17164 case Builtin::BI__builtin_operator_delete:
17176bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *
E) {
17178 if (Info.SpeculativeEvaluationDepth)
17182 if (!OperatorDelete
17183 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17184 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
17185 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
17189 const Expr *Arg =
E->getArgument();
17194 if (
Pointer.Designator.Invalid)
17198 if (
Pointer.isNullPointer()) {
17202 if (!Info.getLangOpts().CPlusPlus20)
17203 Info.CCEDiag(
E, diag::note_constexpr_new);
17208 Info,
E,
Pointer,
E->isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
17215 if (!
E->isArrayForm() &&
Pointer.Designator.Entries.size() != 0 &&
17217 Info.FFDiag(
E, diag::note_constexpr_delete_base_nonvirt_dtor)
17224 if (!
E->isArrayForm() && !
E->isGlobalDelete()) {
17226 if (VirtualDelete &&
17228 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
17229 Info.FFDiag(
E, diag::note_constexpr_new_non_replaceable)
17230 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
17236 (*Alloc)->Value, AllocType))
17244 Info.FFDiag(
E, diag::note_constexpr_double_delete);
17254 return VoidExprEvaluator(Info).Visit(
E);
17270 LV.moveInto(Result);
17275 if (!IntExprEvaluator(Info, Result).Visit(
E))
17281 LV.moveInto(Result);
17283 llvm::APFloat F(0.0);
17291 C.moveInto(Result);
17293 if (!FixedPointExprEvaluator(Info, Result).Visit(
E))
return false;
17298 P.moveInto(Result);
17303 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
17310 Info.CurrentCall->createTemporary(
E,
T, ScopeKind::FullExpression, LV);
17315 if (!Info.getLangOpts().CPlusPlus11)
17316 Info.CCEDiag(
E, diag::note_constexpr_nonliteral)
17321 QualType Unqual =
T.getAtomicUnqualifiedType();
17325 E, Unqual, ScopeKind::FullExpression, LV);
17333 }
else if (Info.getLangOpts().CPlusPlus11) {
17334 Info.FFDiag(
E, diag::note_constexpr_nonliteral) <<
E->
getType();
17337 Info.FFDiag(
E, diag::note_invalid_subexpr_in_const_expr);
17348 const Expr *
E,
bool AllowNonLiteralTypes) {
17369 QualType Unqual =
T.getAtomicUnqualifiedType();
17390 if (Info.EnableNewConstInterp) {
17391 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
E, Result))
17394 ConstantExprKind::Normal);
17403 LV.setFrom(Info.Ctx, Result);
17410 ConstantExprKind::Normal) &&
17418 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
17420 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
17425 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
17431 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
17432 Result =
APValue(FL->getValue());
17437 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
17443 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
17444 if (CE->hasAPValueResult()) {
17445 APValue APV = CE->getAPValueResult();
17447 Result = std::move(APV);
17523 bool InConstantContext)
const {
17524 assert(!isValueDependent() &&
17525 "Expression evaluator can't be called on a dependent expression.");
17526 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
17527 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17528 Info.InConstantContext = InConstantContext;
17529 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
17533 bool InConstantContext)
const {
17534 assert(!isValueDependent() &&
17535 "Expression evaluator can't be called on a dependent expression.");
17536 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
17544 bool InConstantContext)
const {
17545 assert(!isValueDependent() &&
17546 "Expression evaluator can't be called on a dependent expression.");
17547 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
17548 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17549 Info.InConstantContext = InConstantContext;
17550 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
17555 bool InConstantContext)
const {
17556 assert(!isValueDependent() &&
17557 "Expression evaluator can't be called on a dependent expression.");
17558 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
17559 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
17560 Info.InConstantContext = InConstantContext;
17561 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
17566 bool InConstantContext)
const {
17567 assert(!isValueDependent() &&
17568 "Expression evaluator can't be called on a dependent expression.");
17570 if (!getType()->isRealFloatingType())
17573 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
17585 bool InConstantContext)
const {
17586 assert(!isValueDependent() &&
17587 "Expression evaluator can't be called on a dependent expression.");
17589 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
17590 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
17591 Info.InConstantContext = InConstantContext;
17594 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
17595 Result.HasSideEffects ||
17598 ConstantExprKind::Normal, CheckedTemps))
17601 LV.moveInto(Result.Val);
17608 bool IsConstantDestruction) {
17609 EvalInfo Info(Ctx, EStatus,
17610 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
17611 : EvalInfo::EM_ConstantFold);
17612 Info.setEvaluatingDecl(
Base, DestroyedValue,
17613 EvalInfo::EvaluatingDeclKind::Dtor);
17614 Info.InConstantContext = IsConstantDestruction;
17623 if (!Info.discardCleanups())
17624 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17631 assert(!isValueDependent() &&
17632 "Expression evaluator can't be called on a dependent expression.");
17635 Result.Val.hasValue())
17638 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
17639 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
17640 EvalInfo Info(Ctx, Result, EM);
17641 Info.InConstantContext =
true;
17643 if (Info.EnableNewConstInterp) {
17644 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val, Kind))
17647 getStorageType(Ctx,
this), Result.Val, Kind);
17652 if (Kind == ConstantExprKind::ClassTemplateArgument)
17660 Info.setEvaluatingDecl(
Base, Result.Val);
17668 FullExpressionRAII
Scope(Info);
17670 Result.HasSideEffects || !
Scope.destroy())
17673 if (!Info.discardCleanups())
17674 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17684 if (Kind == ConstantExprKind::ClassTemplateArgument &&
17687 Result.HasSideEffects)) {
17699 bool IsConstantInitialization)
const {
17700 assert(!isValueDependent() &&
17701 "Expression evaluator can't be called on a dependent expression.");
17703 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
17705 llvm::raw_string_ostream OS(Name);
17711 EStatus.
Diag = &Notes;
17713 EvalInfo Info(Ctx, EStatus,
17714 (IsConstantInitialization &&
17716 ? EvalInfo::EM_ConstantExpression
17717 : EvalInfo::EM_ConstantFold);
17718 Info.setEvaluatingDecl(VD,
Value);
17719 Info.InConstantContext = IsConstantInitialization;
17724 if (Info.EnableNewConstInterp) {
17725 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
17726 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
17730 ConstantExprKind::Normal);
17745 FullExpressionRAII
Scope(Info);
17748 EStatus.HasSideEffects)
17754 Info.performLifetimeExtension();
17756 if (!Info.discardCleanups())
17757 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
17761 ConstantExprKind::Normal) &&
17768 EStatus.
Diag = &Notes;
17772 bool IsConstantDestruction = hasConstantInitialization();
17778 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
17779 DestroyedValue = *getEvaluatedValue();
17784 getType(), getLocation(), EStatus,
17785 IsConstantDestruction) ||
17789 ensureEvaluatedStmt()->HasConstantDestruction =
true;
17796 assert(!isValueDependent() &&
17797 "Expression evaluator can't be called on a dependent expression.");
17806 assert(!isValueDependent() &&
17807 "Expression evaluator can't be called on a dependent expression.");
17809 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
17812 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17813 Info.InConstantContext =
true;
17817 assert(Result &&
"Could not evaluate expression");
17818 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17820 return EVResult.Val.getInt();
17825 assert(!isValueDependent() &&
17826 "Expression evaluator can't be called on a dependent expression.");
17828 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
17831 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17832 Info.InConstantContext =
true;
17833 Info.CheckingForUndefinedBehavior =
true;
17837 assert(Result &&
"Could not evaluate expression");
17838 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
17840 return EVResult.Val.getInt();
17844 assert(!isValueDependent() &&
17845 "Expression evaluator can't be called on a dependent expression.");
17847 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
17851 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
17852 Info.CheckingForUndefinedBehavior =
true;
17884 IK_ICEIfUnevaluated,
17900static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
17905 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
17907 Info.InConstantContext =
true;
17921#define ABSTRACT_STMT(Node)
17922#define STMT(Node, Base) case Expr::Node##Class:
17923#define EXPR(Node, Base)
17924#include "clang/AST/StmtNodes.inc"
17925 case Expr::PredefinedExprClass:
17926 case Expr::FloatingLiteralClass:
17927 case Expr::ImaginaryLiteralClass:
17928 case Expr::StringLiteralClass:
17929 case Expr::ArraySubscriptExprClass:
17930 case Expr::MatrixSubscriptExprClass:
17931 case Expr::ArraySectionExprClass:
17932 case Expr::OMPArrayShapingExprClass:
17933 case Expr::OMPIteratorExprClass:
17934 case Expr::MemberExprClass:
17935 case Expr::CompoundAssignOperatorClass:
17936 case Expr::CompoundLiteralExprClass:
17937 case Expr::ExtVectorElementExprClass:
17938 case Expr::DesignatedInitExprClass:
17939 case Expr::ArrayInitLoopExprClass:
17940 case Expr::ArrayInitIndexExprClass:
17941 case Expr::NoInitExprClass:
17942 case Expr::DesignatedInitUpdateExprClass:
17943 case Expr::ImplicitValueInitExprClass:
17944 case Expr::ParenListExprClass:
17945 case Expr::VAArgExprClass:
17946 case Expr::AddrLabelExprClass:
17947 case Expr::StmtExprClass:
17948 case Expr::CXXMemberCallExprClass:
17949 case Expr::CUDAKernelCallExprClass:
17950 case Expr::CXXAddrspaceCastExprClass:
17951 case Expr::CXXDynamicCastExprClass:
17952 case Expr::CXXTypeidExprClass:
17953 case Expr::CXXUuidofExprClass:
17954 case Expr::MSPropertyRefExprClass:
17955 case Expr::MSPropertySubscriptExprClass:
17956 case Expr::CXXNullPtrLiteralExprClass:
17957 case Expr::UserDefinedLiteralClass:
17958 case Expr::CXXThisExprClass:
17959 case Expr::CXXThrowExprClass:
17960 case Expr::CXXNewExprClass:
17961 case Expr::CXXDeleteExprClass:
17962 case Expr::CXXPseudoDestructorExprClass:
17963 case Expr::UnresolvedLookupExprClass:
17964 case Expr::RecoveryExprClass:
17965 case Expr::DependentScopeDeclRefExprClass:
17966 case Expr::CXXConstructExprClass:
17967 case Expr::CXXInheritedCtorInitExprClass:
17968 case Expr::CXXStdInitializerListExprClass:
17969 case Expr::CXXBindTemporaryExprClass:
17970 case Expr::ExprWithCleanupsClass:
17971 case Expr::CXXTemporaryObjectExprClass:
17972 case Expr::CXXUnresolvedConstructExprClass:
17973 case Expr::CXXDependentScopeMemberExprClass:
17974 case Expr::UnresolvedMemberExprClass:
17975 case Expr::ObjCStringLiteralClass:
17976 case Expr::ObjCBoxedExprClass:
17977 case Expr::ObjCArrayLiteralClass:
17978 case Expr::ObjCDictionaryLiteralClass:
17979 case Expr::ObjCEncodeExprClass:
17980 case Expr::ObjCMessageExprClass:
17981 case Expr::ObjCSelectorExprClass:
17982 case Expr::ObjCProtocolExprClass:
17983 case Expr::ObjCIvarRefExprClass:
17984 case Expr::ObjCPropertyRefExprClass:
17985 case Expr::ObjCSubscriptRefExprClass:
17986 case Expr::ObjCIsaExprClass:
17987 case Expr::ObjCAvailabilityCheckExprClass:
17988 case Expr::ShuffleVectorExprClass:
17989 case Expr::ConvertVectorExprClass:
17990 case Expr::BlockExprClass:
17991 case Expr::NoStmtClass:
17992 case Expr::OpaqueValueExprClass:
17993 case Expr::PackExpansionExprClass:
17994 case Expr::SubstNonTypeTemplateParmPackExprClass:
17995 case Expr::FunctionParmPackExprClass:
17996 case Expr::AsTypeExprClass:
17997 case Expr::ObjCIndirectCopyRestoreExprClass:
17998 case Expr::MaterializeTemporaryExprClass:
17999 case Expr::PseudoObjectExprClass:
18000 case Expr::AtomicExprClass:
18001 case Expr::LambdaExprClass:
18002 case Expr::CXXFoldExprClass:
18003 case Expr::CoawaitExprClass:
18004 case Expr::DependentCoawaitExprClass:
18005 case Expr::CoyieldExprClass:
18006 case Expr::SYCLUniqueStableNameExprClass:
18007 case Expr::CXXParenListInitExprClass:
18008 case Expr::HLSLOutArgExprClass:
18011 case Expr::InitListExprClass: {
18017 if (cast<InitListExpr>(
E)->getNumInits() == 1)
18018 return CheckICE(cast<InitListExpr>(
E)->getInit(0), Ctx);
18022 case Expr::SizeOfPackExprClass:
18023 case Expr::GNUNullExprClass:
18024 case Expr::SourceLocExprClass:
18025 case Expr::EmbedExprClass:
18026 case Expr::OpenACCAsteriskSizeExprClass:
18029 case Expr::PackIndexingExprClass:
18030 return CheckICE(cast<PackIndexingExpr>(
E)->getSelectedExpr(), Ctx);
18032 case Expr::SubstNonTypeTemplateParmExprClass:
18034 CheckICE(cast<SubstNonTypeTemplateParmExpr>(
E)->getReplacement(), Ctx);
18036 case Expr::ConstantExprClass:
18037 return CheckICE(cast<ConstantExpr>(
E)->getSubExpr(), Ctx);
18039 case Expr::ParenExprClass:
18040 return CheckICE(cast<ParenExpr>(
E)->getSubExpr(), Ctx);
18041 case Expr::GenericSelectionExprClass:
18042 return CheckICE(cast<GenericSelectionExpr>(
E)->getResultExpr(), Ctx);
18043 case Expr::IntegerLiteralClass:
18044 case Expr::FixedPointLiteralClass:
18045 case Expr::CharacterLiteralClass:
18046 case Expr::ObjCBoolLiteralExprClass:
18047 case Expr::CXXBoolLiteralExprClass:
18048 case Expr::CXXScalarValueInitExprClass:
18049 case Expr::TypeTraitExprClass:
18050 case Expr::ConceptSpecializationExprClass:
18051 case Expr::RequiresExprClass:
18052 case Expr::ArrayTypeTraitExprClass:
18053 case Expr::ExpressionTraitExprClass:
18054 case Expr::CXXNoexceptExprClass:
18056 case Expr::CallExprClass:
18057 case Expr::CXXOperatorCallExprClass: {
18061 const CallExpr *CE = cast<CallExpr>(
E);
18066 case Expr::CXXRewrittenBinaryOperatorClass:
18067 return CheckICE(cast<CXXRewrittenBinaryOperator>(
E)->getSemanticForm(),
18069 case Expr::DeclRefExprClass: {
18070 const NamedDecl *
D = cast<DeclRefExpr>(
E)->getDecl();
18071 if (isa<EnumConstantDecl>(
D))
18083 const VarDecl *VD = dyn_cast<VarDecl>(
D);
18090 case Expr::UnaryOperatorClass: {
18113 llvm_unreachable(
"invalid unary operator class");
18115 case Expr::OffsetOfExprClass: {
18124 case Expr::UnaryExprOrTypeTraitExprClass: {
18126 if ((Exp->
getKind() == UETT_SizeOf) &&
18129 if (Exp->
getKind() == UETT_CountOf) {
18136 if (VAT->getElementType()->isArrayType())
18148 case Expr::BinaryOperatorClass: {
18193 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
18196 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
18197 if (REval.isSigned() && REval.isAllOnes()) {
18199 if (LEval.isMinSignedValue())
18200 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
18208 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
18209 return ICEDiag(IK_ICEIfUnevaluated,
E->
getBeginLoc());
18215 return Worst(LHSResult, RHSResult);
18221 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
18231 return Worst(LHSResult, RHSResult);
18234 llvm_unreachable(
"invalid binary operator kind");
18236 case Expr::ImplicitCastExprClass:
18237 case Expr::CStyleCastExprClass:
18238 case Expr::CXXFunctionalCastExprClass:
18239 case Expr::CXXStaticCastExprClass:
18240 case Expr::CXXReinterpretCastExprClass:
18241 case Expr::CXXConstCastExprClass:
18242 case Expr::ObjCBridgedCastExprClass: {
18243 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
18244 if (isa<ExplicitCastExpr>(
E)) {
18249 APSInt IgnoredVal(DestWidth, !DestSigned);
18254 if (FL->getValue().convertToInteger(IgnoredVal,
18255 llvm::APFloat::rmTowardZero,
18256 &Ignored) & APFloat::opInvalidOp)
18261 switch (cast<CastExpr>(
E)->getCastKind()) {
18262 case CK_LValueToRValue:
18263 case CK_AtomicToNonAtomic:
18264 case CK_NonAtomicToAtomic:
18266 case CK_IntegralToBoolean:
18267 case CK_IntegralCast:
18273 case Expr::BinaryConditionalOperatorClass: {
18276 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
18278 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
18279 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
18280 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
18282 return FalseResult;
18284 case Expr::ConditionalOperatorClass: {
18292 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
18295 if (CondResult.Kind == IK_NotICE)
18301 if (TrueResult.Kind == IK_NotICE)
18303 if (FalseResult.Kind == IK_NotICE)
18304 return FalseResult;
18305 if (CondResult.Kind == IK_ICEIfUnevaluated)
18307 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
18313 return FalseResult;
18316 case Expr::CXXDefaultArgExprClass:
18317 return CheckICE(cast<CXXDefaultArgExpr>(
E)->getExpr(), Ctx);
18318 case Expr::CXXDefaultInitExprClass:
18319 return CheckICE(cast<CXXDefaultInitExpr>(
E)->getExpr(), Ctx);
18320 case Expr::ChooseExprClass: {
18321 return CheckICE(cast<ChooseExpr>(
E)->getChosenSubExpr(), Ctx);
18323 case Expr::BuiltinBitCastExprClass: {
18324 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(
E)))
18326 return CheckICE(cast<CastExpr>(
E)->getSubExpr(), Ctx);
18330 llvm_unreachable(
"Invalid StmtClass!");
18336 llvm::APSInt *
Value) {
18344 if (!Result.isInt())
18352 assert(!isValueDependent() &&
18353 "Expression evaluator can't be called on a dependent expression.");
18355 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
18361 if (
D.
Kind != IK_ICE)
18366std::optional<llvm::APSInt>
18368 if (isValueDependent()) {
18370 return std::nullopt;
18377 return std::nullopt;
18380 if (!isIntegerConstantExpr(Ctx))
18381 return std::nullopt;
18389 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
18390 Info.InConstantContext =
true;
18393 llvm_unreachable(
"ICE cannot be evaluated!");
18399 assert(!isValueDependent() &&
18400 "Expression evaluator can't be called on a dependent expression.");
18402 return CheckICE(
this, Ctx).Kind == IK_ICE;
18406 assert(!isValueDependent() &&
18407 "Expression evaluator can't be called on a dependent expression.");
18424 Status.Diag = &Diags;
18425 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
18431 Info.discardCleanups() && !Status.HasSideEffects;
18433 return IsConstExpr && Diags.empty();
18440 assert(!isValueDependent() &&
18441 "Expression evaluator can't be called on a dependent expression.");
18443 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
18445 llvm::raw_string_ostream OS(Name);
18452 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
18453 Info.InConstantContext =
true;
18456 const LValue *ThisPtr =
nullptr;
18459 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
18460 assert(MD &&
"Don't provide `this` for non-methods.");
18461 assert(MD->isImplicitObjectMemberFunction() &&
18462 "Don't provide `this` for methods without an implicit object.");
18464 if (!
This->isValueDependent() &&
18466 !Info.EvalStatus.HasSideEffects)
18467 ThisPtr = &ThisVal;
18471 Info.EvalStatus.HasSideEffects =
false;
18474 CallRef
Call = Info.CurrentCall->createCall(Callee);
18477 unsigned Idx = I - Args.begin();
18478 if (Idx >= Callee->getNumParams())
18480 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
18481 if ((*I)->isValueDependent() ||
18483 Info.EvalStatus.HasSideEffects) {
18485 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
18491 Info.EvalStatus.HasSideEffects =
false;
18496 Info.discardCleanups();
18497 Info.EvalStatus.HasSideEffects =
false;
18500 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
18503 FullExpressionRAII
Scope(Info);
18505 !Info.EvalStatus.HasSideEffects;
18517 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
18519 llvm::raw_string_ostream OS(Name);
18526 Status.Diag = &Diags;
18528 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
18529 Info.InConstantContext =
true;
18530 Info.CheckingPotentialConstantExpression =
true;
18533 if (Info.EnableNewConstInterp) {
18534 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
18535 return Diags.empty();
18546 This.set({&VIE, Info.CurrentCall->Index});
18554 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
18560 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
18564 return Diags.empty();
18572 "Expression evaluator can't be called on a dependent expression.");
18575 Status.Diag = &Diags;
18578 EvalInfo::EM_ConstantExpressionUnevaluated);
18579 Info.InConstantContext =
true;
18580 Info.CheckingPotentialConstantExpression =
true;
18582 if (Info.EnableNewConstInterp) {
18583 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info,
E, FD);
18584 return Diags.empty();
18589 nullptr, CallRef());
18593 return Diags.empty();
18597 unsigned Type)
const {
18598 if (!getType()->isPointerType())
18602 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18607 EvalInfo &Info, std::string *StringResult) {
18619 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
18620 String.getLValueBase().dyn_cast<
const Expr *>())) {
18621 StringRef Str = S->getBytes();
18622 int64_t Off = String.Offset.getQuantity();
18623 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
18624 S->getCharByteWidth() == 1 &&
18626 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
18627 Str = Str.substr(Off);
18629 StringRef::size_type Pos = Str.find(0);
18630 if (Pos != StringRef::npos)
18631 Str = Str.substr(0, Pos);
18633 Result = Str.size();
18635 *StringResult = Str;
18643 for (uint64_t Strlen = 0; ; ++Strlen) {
18651 }
else if (StringResult)
18652 StringResult->push_back(Char.
getInt().getExtValue());
18660 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18662 std::string StringResult;
18665 return StringResult;
18669template <
typename T>
18671 const Expr *SizeExpression,
18672 const Expr *PtrExpression,
18675 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
18676 Info.InConstantContext =
true;
18678 if (Info.EnableNewConstInterp)
18679 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
18680 PtrExpression, Result);
18683 FullExpressionRAII
Scope(Info);
18688 uint64_t Size = SizeValue.getZExtValue();
18691 if constexpr (std::is_same_v<APValue, T>)
18694 if (Size < Result.max_size())
18695 Result.reserve(Size);
18701 for (uint64_t I = 0; I < Size; ++I) {
18707 if constexpr (std::is_same_v<APValue, T>) {
18708 Result.getArrayInitializedElt(I) = std::move(Char);
18712 assert(
C.getBitWidth() <= 8 &&
18713 "string element not representable in char");
18715 Result.push_back(
static_cast<char>(
C.getExtValue()));
18726 const Expr *SizeExpression,
18730 PtrExpression, Ctx, Status);
18734 const Expr *SizeExpression,
18738 PtrExpression, Ctx, Status);
18743 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
18745 if (Info.EnableNewConstInterp)
18746 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this, Result);
18752struct IsWithinLifetimeHandler {
18754 static constexpr AccessKinds AccessKind = AccessKinds::AK_IsWithinLifetime;
18755 using result_type = std::optional<bool>;
18756 std::optional<bool> failed() {
return std::nullopt; }
18757 template <
typename T>
18758 std::optional<bool> found(
T &Subobj,
QualType SubobjType) {
18763std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
18765 EvalInfo &Info = IEE.Info;
18770 if (!Info.InConstantContext)
18771 return std::nullopt;
18772 assert(
E->getBuiltinCallee() == Builtin::BI__builtin_is_within_lifetime);
18773 const Expr *Arg =
E->getArg(0);
18775 return std::nullopt;
18778 return std::nullopt;
18780 if (Val.allowConstexprUnknown())
18784 bool CalledFromStd =
false;
18785 const auto *
Callee = Info.CurrentCall->getCallee();
18786 if (Callee &&
Callee->isInStdNamespace()) {
18790 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
18792 diag::err_invalid_is_within_lifetime)
18793 << (CalledFromStd ?
"std::is_within_lifetime"
18794 :
"__builtin_is_within_lifetime")
18796 return std::nullopt;
18806 if (Val.isNullPointer() || Val.getLValueBase().isNull())
18808 QualType T = Val.getLValueBase().getType();
18810 "Pointers to functions should have been typed as function pointers "
18811 "which would have been rejected earlier");
18814 if (Val.getLValueDesignator().isOnePastTheEnd())
18816 assert(Val.getLValueDesignator().isValidSubobject() &&
18817 "Unchecked case for valid subobject");
18821 CompleteObject CO =
18825 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
18830 IsWithinLifetimeHandler handler{Info};
18831 return findSubobject(Info,
E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info, std::string *StringResult=nullptr)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize.
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid).
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object.
static bool EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool isModification(AccessKinds AK)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E.
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout.
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue.
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue.
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned.
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
AddrLabelExpr - The GNU address of label extension, representing &&label.
LabelDecl * getLabel() const
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Represents a loop initializing the elements of an array.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
bool isComparisonOp() const
static Opcode getOpForCompoundAssignment(Opcode Opc)
A binding in a decomposition declaration.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a C++2a __builtin_bit_cast(T, v) expression.
This class is used for builtin types like 'int'.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Represents a delete expression for memory deallocation and destructor calls, e.g.
Represents a C++ destructor within a class.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
base_class_iterator bases_end()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Represents the this expression in C++.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
const ComparisonCategoryInfo & getInfoForType(QualType Ty) const
Return the comparison category information as specified by getCategoryForType(Ty).
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConditionalOperator - The ?: ternary operator.
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents the current source location and context used to determine the value of the source location...
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
Kind
Lists the kind of concrete classes of Decl.
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
Represents a reference to #emded data.
An instance of this object exists for each enum constant that is defined.
EnumDecl * getDefinitionOrSelf() const
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getOriginalDecl() const
ExplicitCastExpr - An explicit cast written in the source code.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
void EvaluateForOverflow(const ASTContext &Ctx) const
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
ObjCEncodeExpr, used for @encode in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
A partial diagnostic which we might know in advance that we are not going to emit.
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Represents an expression that computes the length of a parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
uint32_t getCodeUnit(size_t i) const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
A template parameter object.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
The base class of the type hierarchy.
bool isStructureType() const
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
The JSON file list parser is used to communicate input to InstallAPI.
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
ActionResult< Expr * > ExprResult
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasUndefinedBehavior
Whether the evaluation hit undefined behavior.
bool HasSideEffects
Whether the evaluated expression has side effects.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
static ObjectUnderConstruction getTombstoneKey()
DenseMapInfo< APValue::LValueBase > Base
static ObjectUnderConstruction getEmptyKey()
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)