56#include "llvm/ADT/APFixedPoint.h"
57#include "llvm/ADT/SmallBitVector.h"
58#include "llvm/ADT/StringExtras.h"
59#include "llvm/Support/Debug.h"
60#include "llvm/Support/SaveAndRestore.h"
61#include "llvm/Support/TimeProfiler.h"
62#include "llvm/Support/raw_ostream.h"
67#define DEBUG_TYPE "exprconstant"
70using llvm::APFixedPoint;
74using llvm::FixedPointSemantics;
81 using SourceLocExprScopeGuard =
113 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
115 return DirectCallee->getAttr<AllocSizeAttr>();
117 return IndirectCallee->getAttr<AllocSizeAttr>();
125 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
133 if (
const auto *FE = dyn_cast<FullExpr>(E))
136 if (
const auto *Cast = dyn_cast<CastExpr>(E))
137 E = Cast->getSubExpr()->IgnoreParens();
139 if (
const auto *CE = dyn_cast<CallExpr>(E))
140 return getAllocSizeAttr(CE) ? CE :
nullptr;
147 const auto *E =
Base.dyn_cast<
const Expr *>();
148 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
156 case ConstantExprKind::Normal:
157 case ConstantExprKind::ClassTemplateArgument:
158 case ConstantExprKind::ImmediateInvocation:
163 case ConstantExprKind::NonClassTemplateArgument:
166 llvm_unreachable(
"unknown ConstantExprKind");
171 case ConstantExprKind::Normal:
172 case ConstantExprKind::ImmediateInvocation:
175 case ConstantExprKind::ClassTemplateArgument:
176 case ConstantExprKind::NonClassTemplateArgument:
179 llvm_unreachable(
"unknown ConstantExprKind");
185 static const uint64_t AssumedSizeForUnsizedArray =
186 std::numeric_limits<uint64_t>::max() / 2;
196 bool &FirstEntryIsUnsizedArray) {
199 assert(!isBaseAnAllocSizeCall(
Base) &&
200 "Unsized arrays shouldn't appear here");
201 unsigned MostDerivedLength = 0;
204 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
208 MostDerivedLength = I + 1;
211 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
212 ArraySize = CAT->getZExtSize();
214 assert(I == 0 &&
"unexpected unsized array designator");
215 FirstEntryIsUnsizedArray =
true;
216 ArraySize = AssumedSizeForUnsizedArray;
222 MostDerivedLength = I + 1;
224 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
225 Type = FD->getType();
227 MostDerivedLength = I + 1;
235 return MostDerivedLength;
239 struct SubobjectDesignator {
243 LLVM_PREFERRED_TYPE(
bool)
244 unsigned Invalid : 1;
247 LLVM_PREFERRED_TYPE(
bool)
248 unsigned IsOnePastTheEnd : 1;
251 LLVM_PREFERRED_TYPE(
bool)
252 unsigned FirstEntryIsAnUnsizedArray : 1;
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned MostDerivedIsArrayElement : 1;
260 unsigned MostDerivedPathLength : 28;
269 uint64_t MostDerivedArraySize;
279 SubobjectDesignator() : Invalid(
true) {}
282 : Invalid(
false), IsOnePastTheEnd(
false),
283 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
284 MostDerivedPathLength(0), MostDerivedArraySize(0),
285 MostDerivedType(
T) {}
288 : Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
289 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
290 MostDerivedPathLength(0), MostDerivedArraySize(0) {
291 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
293 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
295 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
296 if (
V.getLValueBase()) {
297 bool IsArray =
false;
298 bool FirstIsUnsizedArray =
false;
299 MostDerivedPathLength = findMostDerivedSubobject(
300 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
301 MostDerivedType, IsArray, FirstIsUnsizedArray);
302 MostDerivedIsArrayElement = IsArray;
303 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
309 unsigned NewLength) {
313 assert(
Base &&
"cannot truncate path for null pointer");
314 assert(NewLength <= Entries.size() &&
"not a truncation");
316 if (NewLength == Entries.size())
318 Entries.resize(NewLength);
320 bool IsArray =
false;
321 bool FirstIsUnsizedArray =
false;
322 MostDerivedPathLength = findMostDerivedSubobject(
323 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
324 FirstIsUnsizedArray);
325 MostDerivedIsArrayElement = IsArray;
326 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
336 bool isMostDerivedAnUnsizedArray()
const {
337 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
338 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
343 uint64_t getMostDerivedArraySize()
const {
344 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
345 return MostDerivedArraySize;
349 bool isOnePastTheEnd()
const {
353 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
354 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
355 MostDerivedArraySize)
363 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
364 if (Invalid || isMostDerivedAnUnsizedArray())
370 bool IsArray = MostDerivedPathLength == Entries.size() &&
371 MostDerivedIsArrayElement;
372 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
373 : (uint64_t)IsOnePastTheEnd;
375 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
376 return {ArrayIndex, ArraySize - ArrayIndex};
380 bool isValidSubobject()
const {
383 return !isOnePastTheEnd();
391 assert(!Invalid &&
"invalid designator has no subobject type");
392 return MostDerivedPathLength == Entries.size()
403 MostDerivedIsArrayElement =
true;
405 MostDerivedPathLength = Entries.size();
409 void addUnsizedArrayUnchecked(
QualType ElemTy) {
412 MostDerivedType = ElemTy;
413 MostDerivedIsArrayElement =
true;
417 MostDerivedArraySize = AssumedSizeForUnsizedArray;
418 MostDerivedPathLength = Entries.size();
422 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
426 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
427 MostDerivedType = FD->getType();
428 MostDerivedIsArrayElement =
false;
429 MostDerivedArraySize = 0;
430 MostDerivedPathLength = Entries.size();
434 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
439 MostDerivedType = EltTy;
440 MostDerivedIsArrayElement =
true;
441 MostDerivedArraySize = 2;
442 MostDerivedPathLength = Entries.size();
444 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
445 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
448 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N) {
449 if (Invalid || !N)
return;
450 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
451 if (isMostDerivedAnUnsizedArray()) {
452 diagnoseUnsizedArrayPointerArithmetic(Info, E);
457 Entries.back().getAsArrayIndex() + TruncatedN);
464 bool IsArray = MostDerivedPathLength == Entries.size() &&
465 MostDerivedIsArrayElement;
466 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
467 : (uint64_t)IsOnePastTheEnd;
469 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
471 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
474 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
475 (llvm::APInt&)N += ArrayIndex;
476 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
477 diagnosePointerArithmetic(Info, E, N);
482 ArrayIndex += TruncatedN;
483 assert(ArrayIndex <= ArraySize &&
484 "bounds check succeeded for out-of-bounds index");
489 IsOnePastTheEnd = (ArrayIndex != 0);
494 enum class ScopeKind {
502 CallRef() : OrigCallee(), CallIndex(0), Version() {}
503 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
504 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
506 explicit operator bool()
const {
return OrigCallee; }
532 CallStackFrame *Caller;
554 typedef std::pair<const void *, unsigned> MapKeyTy;
555 typedef std::map<MapKeyTy, APValue>
MapTy;
567 unsigned CurTempVersion = TempVersionStack.back();
569 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
571 void pushTempVersion() {
572 TempVersionStack.push_back(++CurTempVersion);
575 void popTempVersion() {
576 TempVersionStack.pop_back();
580 return {Callee, Index, ++CurTempVersion};
591 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
592 FieldDecl *LambdaThisCaptureField =
nullptr;
594 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
600 APValue *getTemporary(
const void *Key,
unsigned Version) {
601 MapKeyTy KV(Key, Version);
602 auto LB = Temporaries.lower_bound(KV);
603 if (LB != Temporaries.end() && LB->first == KV)
609 APValue *getCurrentTemporary(
const void *Key) {
610 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
611 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
612 return &std::prev(UB)->second;
617 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
618 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
619 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
620 return std::prev(UB)->first.second;
628 template<
typename KeyT>
630 ScopeKind
Scope, LValue &LV);
635 void describe(llvm::raw_ostream &OS)
const override;
637 Frame *getCaller()
const override {
return Caller; }
638 SourceRange getCallRange()
const override {
return CallRange; }
639 const FunctionDecl *getCallee()
const override {
return Callee; }
641 bool isStdFunction()
const {
642 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
643 if (DC->isStdNamespace())
650 bool CanEvalMSConstexpr =
false;
658 class ThisOverrideRAII {
660 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
661 : Frame(Frame), OldThis(Frame.This) {
663 Frame.This = NewThis;
665 ~ThisOverrideRAII() {
666 Frame.This = OldThis;
669 CallStackFrame &Frame;
670 const LValue *OldThis;
675 class ExprTimeTraceScope {
677 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
678 : TimeScope(Name, [E, &Ctx] {
683 llvm::TimeTraceScope TimeScope;
688 struct MSConstexprContextRAII {
689 CallStackFrame &Frame;
691 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
692 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
693 Frame.CanEvalMSConstexpr =
Value;
696 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
701 const LValue &This,
QualType ThisType);
709 llvm::PointerIntPair<APValue*, 2, ScopeKind>
Value;
720 bool isDestroyedAtEndOf(ScopeKind K)
const {
721 return (
int)
Value.getInt() >= (
int)K;
723 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
724 if (RunDestructors) {
727 Loc = VD->getLocation();
729 Loc = E->getExprLoc();
736 bool hasSideEffect() {
737 return T.isDestructedType();
742 struct ObjectUnderConstruction {
745 friend bool operator==(
const ObjectUnderConstruction &LHS,
746 const ObjectUnderConstruction &RHS) {
747 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
749 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
750 return llvm::hash_combine(Obj.Base, Obj.Path);
753 enum class ConstructionPhase {
764template<>
struct DenseMapInfo<ObjectUnderConstruction> {
765 using Base = DenseMapInfo<APValue::LValueBase>;
767 return {Base::getEmptyKey(), {}}; }
769 return {Base::getTombstoneKey(), {}};
774 static bool isEqual(
const ObjectUnderConstruction &LHS,
775 const ObjectUnderConstruction &RHS) {
789 const Expr *AllocExpr =
nullptr;
800 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
801 return NE->isArray() ? ArrayNew : New;
802 assert(isa<CallExpr>(AllocExpr));
807 struct DynAllocOrder {
835 CallStackFrame *CurrentCall;
838 unsigned CallStackDepth;
841 unsigned NextCallIndex;
850 bool EnableNewConstInterp;
854 CallStackFrame BottomFrame;
864 enum class EvaluatingDeclKind {
871 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
878 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
879 ObjectsUnderConstruction;
884 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
887 unsigned NumHeapAllocs = 0;
889 struct EvaluatingConstructorRAII {
891 ObjectUnderConstruction
Object;
893 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
897 EI.ObjectsUnderConstruction
898 .insert({
Object, HasBases ? ConstructionPhase::Bases
899 : ConstructionPhase::AfterBases})
902 void finishedConstructingBases() {
903 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterBases;
905 void finishedConstructingFields() {
906 EI.ObjectsUnderConstruction[
Object] = ConstructionPhase::AfterFields;
908 ~EvaluatingConstructorRAII() {
909 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
913 struct EvaluatingDestructorRAII {
915 ObjectUnderConstruction
Object;
917 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
919 DidInsert = EI.ObjectsUnderConstruction
920 .insert({
Object, ConstructionPhase::Destroying})
923 void startedDestroyingBases() {
924 EI.ObjectsUnderConstruction[
Object] =
925 ConstructionPhase::DestroyingBases;
927 ~EvaluatingDestructorRAII() {
929 EI.ObjectsUnderConstruction.erase(Object);
936 return ObjectsUnderConstruction.lookup({
Base, Path});
941 unsigned SpeculativeEvaluationDepth = 0;
949 bool HasActiveDiagnostic;
953 bool HasFoldFailureDiagnostic;
958 bool CheckingPotentialConstantExpression =
false;
966 bool CheckingForUndefinedBehavior =
false;
968 enum EvaluationMode {
971 EM_ConstantExpression,
978 EM_ConstantExpressionUnevaluated,
986 EM_IgnoreSideEffects,
991 bool checkingPotentialConstantExpression()
const override {
992 return CheckingPotentialConstantExpression;
998 bool checkingForUndefinedBehavior()
const override {
999 return CheckingForUndefinedBehavior;
1003 : Ctx(const_cast<
ASTContext &>(
C)), EvalStatus(S), CurrentCall(nullptr),
1004 CallStackDepth(0), NextCallIndex(1),
1005 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
1006 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
1009 nullptr, CallRef()),
1010 EvaluatingDecl((const
ValueDecl *)nullptr),
1011 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
1012 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
1018 ASTContext &getCtx()
const override {
return Ctx; }
1021 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
1022 EvaluatingDecl =
Base;
1023 IsEvaluatingDecl = EDK;
1024 EvaluatingDeclValue = &
Value;
1030 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
1032 if (NextCallIndex == 0) {
1034 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
1037 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
1039 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
1040 << getLangOpts().ConstexprCallDepth;
1045 uint64_t ElemCount,
bool Diag) {
1051 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
1053 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
1063 if (ElemCount > Limit) {
1065 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
1066 << ElemCount << Limit;
1072 std::pair<CallStackFrame *, unsigned>
1073 getCallFrameAndDepth(
unsigned CallIndex) {
1074 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
1077 unsigned Depth = CallStackDepth;
1078 CallStackFrame *Frame = CurrentCall;
1079 while (Frame->Index > CallIndex) {
1080 Frame = Frame->Caller;
1083 if (Frame->Index == CallIndex)
1084 return {Frame, Depth};
1085 return {
nullptr, 0};
1088 bool nextStep(
const Stmt *S) {
1090 FFDiag(S->getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1100 std::optional<DynAlloc *> Result;
1101 auto It = HeapAllocs.find(DA);
1102 if (It != HeapAllocs.end())
1103 Result = &It->second;
1109 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1110 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1115 struct StdAllocatorCaller {
1116 unsigned FrameIndex;
1118 explicit operator bool()
const {
return FrameIndex != 0; };
1121 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1122 for (
const CallStackFrame *
Call = CurrentCall;
Call != &BottomFrame;
1124 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1128 if (!FnII || !FnII->
isStr(FnName))
1132 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1138 if (CTSD->isInStdNamespace() && ClassII &&
1139 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1141 return {
Call->Index, TAL[0].getAsType()};
1147 void performLifetimeExtension() {
1149 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1150 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1157 bool discardCleanups() {
1158 for (Cleanup &
C : CleanupStack) {
1159 if (
C.hasSideEffect() && !noteSideEffect()) {
1160 CleanupStack.clear();
1164 CleanupStack.clear();
1169 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1170 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1172 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1173 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1175 void setFoldFailureDiagnostic(
bool Flag)
override {
1176 HasFoldFailureDiagnostic = Flag;
1187 bool hasPriorDiagnostic()
override {
1188 if (!EvalStatus.
Diag->empty()) {
1190 case EM_ConstantFold:
1191 case EM_IgnoreSideEffects:
1192 if (!HasFoldFailureDiagnostic)
1196 case EM_ConstantExpression:
1197 case EM_ConstantExpressionUnevaluated:
1198 setActiveDiagnostic(
false);
1205 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1210 bool keepEvaluatingAfterSideEffect() {
1212 case EM_IgnoreSideEffects:
1215 case EM_ConstantExpression:
1216 case EM_ConstantExpressionUnevaluated:
1217 case EM_ConstantFold:
1220 return checkingPotentialConstantExpression() ||
1221 checkingForUndefinedBehavior();
1223 llvm_unreachable(
"Missed EvalMode case");
1228 bool noteSideEffect() {
1230 return keepEvaluatingAfterSideEffect();
1234 bool keepEvaluatingAfterUndefinedBehavior() {
1236 case EM_IgnoreSideEffects:
1237 case EM_ConstantFold:
1240 case EM_ConstantExpression:
1241 case EM_ConstantExpressionUnevaluated:
1242 return checkingForUndefinedBehavior();
1244 llvm_unreachable(
"Missed EvalMode case");
1250 bool noteUndefinedBehavior()
override {
1252 return keepEvaluatingAfterUndefinedBehavior();
1257 bool keepEvaluatingAfterFailure()
const override {
1262 case EM_ConstantExpression:
1263 case EM_ConstantExpressionUnevaluated:
1264 case EM_ConstantFold:
1265 case EM_IgnoreSideEffects:
1266 return checkingPotentialConstantExpression() ||
1267 checkingForUndefinedBehavior();
1269 llvm_unreachable(
"Missed EvalMode case");
1282 [[nodiscard]]
bool noteFailure() {
1290 bool KeepGoing = keepEvaluatingAfterFailure();
1295 class ArrayInitLoopIndex {
1300 ArrayInitLoopIndex(EvalInfo &Info)
1301 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1302 Info.ArrayInitIndex = 0;
1304 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1306 operator uint64_t&() {
return Info.ArrayInitIndex; }
1311 struct FoldConstant {
1314 bool HadNoPriorDiags;
1315 EvalInfo::EvaluationMode OldMode;
1317 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1320 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1321 Info.EvalStatus.
Diag->empty() &&
1322 !Info.EvalStatus.HasSideEffects),
1323 OldMode(Info.EvalMode) {
1325 Info.EvalMode = EvalInfo::EM_ConstantFold;
1327 void keepDiagnostics() { Enabled =
false; }
1329 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1330 !Info.EvalStatus.HasSideEffects)
1331 Info.EvalStatus.Diag->clear();
1332 Info.EvalMode = OldMode;
1338 struct IgnoreSideEffectsRAII {
1340 EvalInfo::EvaluationMode OldMode;
1341 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1342 : Info(Info), OldMode(Info.EvalMode) {
1343 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1346 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1351 class SpeculativeEvaluationRAII {
1352 EvalInfo *Info =
nullptr;
1354 unsigned OldSpeculativeEvaluationDepth = 0;
1356 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1358 OldStatus =
Other.OldStatus;
1359 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1360 Other.Info =
nullptr;
1363 void maybeRestoreState() {
1367 Info->EvalStatus = OldStatus;
1368 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1372 SpeculativeEvaluationRAII() =
default;
1374 SpeculativeEvaluationRAII(
1376 : Info(&Info), OldStatus(Info.EvalStatus),
1377 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1378 Info.EvalStatus.Diag = NewDiag;
1379 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1382 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1383 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1384 moveFromAndCancel(std::move(
Other));
1387 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1388 maybeRestoreState();
1389 moveFromAndCancel(std::move(
Other));
1393 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1398 template<ScopeKind Kind>
1401 unsigned OldStackSize;
1403 ScopeRAII(EvalInfo &Info)
1404 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1407 Info.CurrentCall->pushTempVersion();
1409 bool destroy(
bool RunDestructors =
true) {
1410 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1415 if (OldStackSize != -1U)
1419 Info.CurrentCall->popTempVersion();
1422 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1423 unsigned OldStackSize) {
1424 assert(OldStackSize <= Info.CleanupStack.size() &&
1425 "running cleanups out of order?");
1430 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1431 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1432 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1440 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1441 if (Kind != ScopeKind::Block)
1443 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1444 return C.isDestroyedAtEndOf(Kind);
1446 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1450 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1451 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1452 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1455bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1459 if (isOnePastTheEnd()) {
1460 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1471void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1473 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1478void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1483 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1484 Info.CCEDiag(E, diag::note_constexpr_array_index)
1486 <<
static_cast<unsigned>(getMostDerivedArraySize());
1488 Info.CCEDiag(E, diag::note_constexpr_array_index)
1493CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
1498 Index(Info.NextCallIndex++) {
1499 Info.CurrentCall =
this;
1500 ++Info.CallStackDepth;
1503CallStackFrame::~CallStackFrame() {
1504 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1505 --Info.CallStackDepth;
1506 Info.CurrentCall = Caller;
1528 llvm_unreachable(
"unknown access kind");
1562 llvm_unreachable(
"unknown access kind");
1566 struct ComplexValue {
1574 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1576 void makeComplexFloat() { IsInt =
false; }
1577 bool isComplexFloat()
const {
return !IsInt; }
1578 APFloat &getComplexFloatReal() {
return FloatReal; }
1579 APFloat &getComplexFloatImag() {
return FloatImag; }
1581 void makeComplexInt() { IsInt =
true; }
1582 bool isComplexInt()
const {
return IsInt; }
1583 APSInt &getComplexIntReal() {
return IntReal; }
1584 APSInt &getComplexIntImag() {
return IntImag; }
1587 if (isComplexFloat())
1593 assert(
v.isComplexFloat() ||
v.isComplexInt());
1594 if (
v.isComplexFloat()) {
1596 FloatReal =
v.getComplexFloatReal();
1597 FloatImag =
v.getComplexFloatImag();
1600 IntReal =
v.getComplexIntReal();
1601 IntImag =
v.getComplexIntImag();
1611 bool InvalidBase : 1;
1614 CharUnits &getLValueOffset() {
return Offset; }
1615 const CharUnits &getLValueOffset()
const {
return Offset; }
1616 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1617 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1618 bool isNullPointer()
const {
return IsNullPtr;}
1620 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1621 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1627 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1633 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1634 Base =
V.getLValueBase();
1635 Offset =
V.getLValueOffset();
1636 InvalidBase =
false;
1638 IsNullPtr =
V.isNullPointer();
1645 const auto *E = B.
get<
const Expr *>();
1646 assert((isa<MemberExpr>(E) || tryUnwrapAllocSizeCall(E)) &&
1647 "Unexpected type of invalid base");
1653 InvalidBase = BInvalid;
1654 Designator = SubobjectDesignator(getType(B));
1662 InvalidBase =
false;
1673 moveInto(Printable);
1680 template <
typename GenDiagType>
1681 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1693 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1695 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1696 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1700 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1702 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1703 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1714 void addDecl(EvalInfo &Info,
const Expr *E,
1719 void addUnsizedArray(EvalInfo &Info,
const Expr *E,
QualType ElemTy) {
1721 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1726 assert(getType(
Base)->isPointerType() || getType(
Base)->isArrayType());
1727 Designator.FirstEntryIsAnUnsizedArray =
true;
1735 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1739 void clearIsNullPointer() {
1742 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1752 uint64_t Offset64 = Offset.getQuantity();
1754 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1759 clearIsNullPointer();
1764 clearIsNullPointer();
1771 : DeclAndIsDerivedMember(
Decl,
false) {}
1776 return DeclAndIsDerivedMember.getPointer();
1779 bool isDerivedMember()
const {
1780 return DeclAndIsDerivedMember.getInt();
1784 return cast<CXXRecordDecl>(
1785 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1789 V =
APValue(getDecl(), isDerivedMember(), Path);
1792 assert(
V.isMemberPointer());
1793 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1794 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1797 Path.insert(Path.end(),
P.begin(),
P.end());
1803 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1811 assert(!Path.empty());
1813 if (Path.size() >= 2)
1817 if (
Expected->getCanonicalDecl() !=
Class->getCanonicalDecl()) {
1833 if (!isDerivedMember()) {
1834 Path.push_back(Derived);
1837 if (!castBack(Derived))
1840 DeclAndIsDerivedMember.setInt(
false);
1848 DeclAndIsDerivedMember.setInt(
true);
1849 if (isDerivedMember()) {
1850 Path.push_back(
Base);
1853 return castBack(
Base);
1858 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1859 if (!LHS.getDecl() || !RHS.getDecl())
1860 return !LHS.getDecl() && !RHS.getDecl();
1861 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1863 return LHS.Path == RHS.Path;
1869 const LValue &This,
const Expr *E,
1870 bool AllowNonLiteralTypes =
false);
1872 bool InvalidBaseOK =
false);
1874 bool InvalidBaseOK =
false);
1904 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1905 Int = Int.extend(Int.getBitWidth() + 1);
1906 Int.setIsSigned(
true);
1911template<
typename KeyT>
1913 ScopeKind
Scope, LValue &LV) {
1914 unsigned Version = getTempVersion();
1923 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1929 return createLocal(
Base, PVD, PVD->
getType(), ScopeKind::Call);
1934 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1935 unsigned Version =
Base.getVersion();
1936 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1937 assert(Result.isAbsent() &&
"local created multiple times");
1943 if (Index <= Info.SpeculativeEvaluationDepth) {
1944 if (
T.isDestructedType())
1945 Info.noteSideEffect();
1947 Info.CleanupStack.push_back(Cleanup(&Result,
Base,
T,
Scope));
1954 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1960 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1961 std::forward_as_tuple(DA), std::tuple<>());
1962 assert(Result.second &&
"reused a heap alloc index?");
1963 Result.first->second.AllocExpr = E;
1964 return &Result.first->second.Value;
1968void CallStackFrame::describe(raw_ostream &Out)
const {
1969 unsigned ArgIndex = 0;
1971 isa<CXXMethodDecl>(Callee) && !isa<CXXConstructorDecl>(Callee) &&
1972 cast<CXXMethodDecl>(Callee)->isImplicitObjectMemberFunction();
1975 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
1978 if (This && IsMemberCall) {
1979 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
1980 const Expr *
Object = MCE->getImplicitObjectArgument();
1981 Object->printPretty(Out,
nullptr, Info.Ctx.getPrintingPolicy(),
1983 if (
Object->getType()->isPointerType())
1987 }
else if (
const auto *OCE =
1988 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
1989 OCE->getArg(0)->printPretty(Out,
nullptr,
1990 Info.Ctx.getPrintingPolicy(),
1995 This->moveInto(Val);
1998 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
2001 Callee->getNameForDiagnostic(Out, Info.Ctx.getPrintingPolicy(),
2003 IsMemberCall =
false;
2009 E =
Callee->param_end(); I != E; ++I, ++ArgIndex) {
2010 if (ArgIndex > (
unsigned)IsMemberCall)
2014 APValue *
V = Info.getParamSlot(Arguments, Param);
2016 V->printPretty(Out, Info.Ctx, Param->
getType());
2020 if (ArgIndex == 0 && IsMemberCall)
2021 Out <<
"->" << *
Callee <<
'(';
2035 return Info.noteSideEffect();
2042 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
2043 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
2044 Builtin == Builtin::BI__builtin_function_start);
2058 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
2059 return VD->hasGlobalStorage();
2060 if (isa<TemplateParamObjectDecl>(D))
2065 return isa<FunctionDecl, MSGuidDecl, UnnamedGlobalConstantDecl>(D);
2075 case Expr::CompoundLiteralExprClass: {
2079 case Expr::MaterializeTemporaryExprClass:
2082 return cast<MaterializeTemporaryExpr>(E)->getStorageDuration() ==
SD_Static;
2084 case Expr::StringLiteralClass:
2085 case Expr::PredefinedExprClass:
2086 case Expr::ObjCStringLiteralClass:
2087 case Expr::ObjCEncodeExprClass:
2089 case Expr::ObjCBoxedExprClass:
2090 return cast<ObjCBoxedExpr>(E)->isExpressibleAsConstantInitializer();
2091 case Expr::CallExprClass:
2094 case Expr::AddrLabelExprClass:
2098 case Expr::BlockExprClass:
2099 return !cast<BlockExpr>(E)->getBlockDecl()->hasCaptures();
2102 case Expr::SourceLocExprClass:
2104 case Expr::ImplicitValueInitExprClass:
2116 return LVal.Base.dyn_cast<
const ValueDecl*>();
2120 if (
Value.getLValueCallIndex())
2123 return E && !isa<MaterializeTemporaryExpr>(E);
2143 if (!A.getLValueBase())
2144 return !B.getLValueBase();
2145 if (!B.getLValueBase())
2148 if (A.getLValueBase().getOpaqueValue() !=
2149 B.getLValueBase().getOpaqueValue())
2152 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2153 A.getLValueVersion() == B.getLValueVersion();
2157 assert(
Base &&
"no location for a null lvalue");
2163 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2165 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2166 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2167 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2168 Idx < F->Callee->getNumParams()) {
2169 VD = F->Callee->getParamDecl(Idx);
2176 Info.Note(VD->
getLocation(), diag::note_declared_at);
2178 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2181 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2182 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2183 diag::note_constexpr_dynamic_alloc_here);
2216 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2224 if (isTemplateArgument(Kind)) {
2225 int InvalidBaseKind = -1;
2228 InvalidBaseKind = 0;
2229 else if (isa_and_nonnull<StringLiteral>(BaseE))
2230 InvalidBaseKind = 1;
2231 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2232 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2233 InvalidBaseKind = 2;
2234 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2235 InvalidBaseKind = 3;
2236 Ident = PE->getIdentKindName();
2239 if (InvalidBaseKind != -1) {
2240 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2241 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2247 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2248 FD && FD->isImmediateFunction()) {
2249 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2251 Info.Note(FD->getLocation(), diag::note_declared_at);
2259 if (Info.getLangOpts().CPlusPlus11) {
2260 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2261 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2263 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2264 if (VarD && VarD->isConstexpr()) {
2270 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2282 assert((Info.checkingPotentialConstantExpression() ||
2283 LVal.getLValueCallIndex() == 0) &&
2284 "have call index for global lvalue");
2287 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2288 << IsReferenceType << !
Designator.Entries.empty();
2294 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2296 if (Var->getTLSKind())
2302 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>())
2308 if (Info.getCtx().getLangOpts().CUDA &&
2309 Info.getCtx().getLangOpts().CUDAIsDevice &&
2310 Info.getCtx().CUDAConstantEvalCtx.NoWrongSidedVars) {
2311 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2312 !Var->hasAttr<CUDAConstantAttr>() &&
2313 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2314 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2315 Var->hasAttr<HIPManagedAttr>())
2319 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2330 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2331 FD->hasAttr<DLLImportAttr>())
2335 }
else if (
const auto *MTE =
2336 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2337 if (CheckedTemps.insert(MTE).second) {
2340 Info.FFDiag(MTE->getExprLoc(),
2341 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2346 APValue *
V = MTE->getOrCreateValue(
false);
2347 assert(
V &&
"evasluation result refers to uninitialised temporary");
2349 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2350 nullptr, CheckedTemps))
2357 if (!IsReferenceType)
2369 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2370 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2385 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2388 if (FD->isImmediateFunction()) {
2389 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2390 Info.Note(FD->getLocation(), diag::note_declared_at);
2393 return isForManglingOnly(Kind) || FD->isVirtual() ||
2394 !FD->hasAttr<DLLImportAttr>();
2400 const LValue *This =
nullptr) {
2417 if (This && Info.EvaluatingDecl == This->getLValueBase())
2421 if (Info.getLangOpts().CPlusPlus11)
2422 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2425 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2436 if (SubobjectDecl) {
2437 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2438 << 1 << SubobjectDecl;
2440 diag::note_constexpr_subobject_declared_here);
2442 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2451 Type = AT->getValueType();
2456 if (
Value.isArray()) {
2458 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2460 Value.getArrayInitializedElt(I), Kind,
2461 SubobjectDecl, CheckedTemps))
2464 if (!
Value.hasArrayFiller())
2467 Value.getArrayFiller(), Kind, SubobjectDecl,
2470 if (
Value.isUnion() &&
Value.getUnionField()) {
2473 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2475 if (
Value.isStruct()) {
2477 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2478 unsigned BaseIndex = 0;
2480 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2483 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2484 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2494 for (
const auto *I : RD->
fields()) {
2495 if (I->isUnnamedBitField())
2499 Value.getStructField(I->getFieldIndex()), Kind,
2505 if (
Value.isLValue() &&
2506 CERK == CheckEvaluationResultKind::ConstantExpression) {
2508 LVal.setFrom(Info.Ctx,
Value);
2513 if (
Value.isMemberPointer() &&
2514 CERK == CheckEvaluationResultKind::ConstantExpression)
2534 nullptr, CheckedTemps);
2543 CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc,
Type,
Value,
2544 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2550 if (!Info.HeapAllocs.empty()) {
2554 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2555 diag::note_constexpr_memory_leak)
2556 <<
unsigned(Info.HeapAllocs.size() - 1);
2564 if (!
Value.getLValueBase()) {
2566 Result = !
Value.getLValueOffset().isZero();
2584 Result = Val.
getInt().getBoolValue();
2616 llvm_unreachable(
"unknown APValue kind");
2622 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2632 Info.CCEDiag(E, diag::note_constexpr_overflow)
2633 << SrcValue << DestType;
2634 return Info.noteUndefinedBehavior();
2640 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2644 Result =
APSInt(DestWidth, !DestSigned);
2646 if (
Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2647 & APFloat::opInvalidOp)
2658 llvm::RoundingMode RM =
2660 if (RM == llvm::RoundingMode::Dynamic)
2661 RM = llvm::RoundingMode::NearestTiesToEven;
2667 APFloat::opStatus St) {
2670 if (Info.InConstantContext)
2674 if ((St & APFloat::opInexact) &&
2678 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2682 if ((St != APFloat::opOK) &&
2685 FPO.getAllowFEnvAccess())) {
2686 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2690 if ((St & APFloat::opStatus::opInvalidOp) &&
2709 assert(isa<CastExpr>(E) || isa<CompoundAssignOperator>(E));
2711 APFloat::opStatus St;
2712 APFloat
Value = Result;
2714 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2721 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2727 Result =
Value.getBoolValue();
2734 QualType DestType, APFloat &Result) {
2735 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2737 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2743 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2745 if (!
Value.isInt()) {
2749 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2755 unsigned OldBitWidth = Int.getBitWidth();
2757 if (NewBitWidth < OldBitWidth)
2758 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2765template<
typename Operation>
2768 unsigned BitWidth, Operation Op,
2770 if (LHS.isUnsigned()) {
2771 Result = Op(LHS, RHS);
2775 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2776 Result =
Value.trunc(LHS.getBitWidth());
2777 if (Result.extend(BitWidth) !=
Value) {
2778 if (Info.checkingForUndefinedBehavior())
2779 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2780 diag::warn_integer_constant_overflow)
2781 <<
toString(Result, 10, Result.isSigned(),
false,
2793 bool HandleOverflowResult =
true;
2800 std::multiplies<APSInt>(), Result);
2803 std::plus<APSInt>(), Result);
2806 std::minus<APSInt>(), Result);
2807 case BO_And: Result = LHS & RHS;
return true;
2808 case BO_Xor: Result = LHS ^ RHS;
return true;
2809 case BO_Or: Result = LHS | RHS;
return true;
2813 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2819 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2820 LHS.isMinSignedValue())
2822 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2823 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2824 return HandleOverflowResult;
2826 if (Info.getLangOpts().OpenCL)
2828 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2829 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2831 else if (RHS.isSigned() && RHS.isNegative()) {
2834 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2841 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2843 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2844 << RHS << E->
getType() << LHS.getBitWidth();
2845 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2850 if (LHS.isNegative())
2851 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2852 else if (LHS.countl_zero() < SA)
2853 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2859 if (Info.getLangOpts().OpenCL)
2861 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2862 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2864 else if (RHS.isSigned() && RHS.isNegative()) {
2867 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2874 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2876 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2877 << RHS << E->
getType() << LHS.getBitWidth();
2882 case BO_LT: Result = LHS < RHS;
return true;
2883 case BO_GT: Result = LHS > RHS;
return true;
2884 case BO_LE: Result = LHS <= RHS;
return true;
2885 case BO_GE: Result = LHS >= RHS;
return true;
2886 case BO_EQ: Result = LHS == RHS;
return true;
2887 case BO_NE: Result = LHS != RHS;
return true;
2889 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2896 const APFloat &RHS) {
2898 APFloat::opStatus St;
2904 St = LHS.multiply(RHS, RM);
2907 St = LHS.add(RHS, RM);
2910 St = LHS.subtract(RHS, RM);
2916 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2917 St = LHS.divide(RHS, RM);
2926 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2927 return Info.noteUndefinedBehavior();
2935 const APInt &RHSValue, APInt &Result) {
2936 bool LHS = (LHSValue != 0);
2937 bool RHS = (RHSValue != 0);
2939 if (Opcode == BO_LAnd)
2940 Result = LHS && RHS;
2942 Result = LHS || RHS;
2947 const APFloat &RHSValue, APInt &Result) {
2948 bool LHS = !LHSValue.isZero();
2949 bool RHS = !RHSValue.isZero();
2951 if (Opcode == BO_LAnd)
2952 Result = LHS && RHS;
2954 Result = LHS || RHS;
2960 const APValue &RHSValue, APInt &Result) {
2964 RHSValue.
getInt(), Result);
2970template <
typename APTy>
2973 const APTy &RHSValue, APInt &Result) {
2976 llvm_unreachable(
"unsupported binary operator");
2978 Result = (LHSValue == RHSValue);
2981 Result = (LHSValue != RHSValue);
2984 Result = (LHSValue < RHSValue);
2987 Result = (LHSValue > RHSValue);
2990 Result = (LHSValue <= RHSValue);
2993 Result = (LHSValue >= RHSValue);
3007 const APValue &RHSValue, APInt &Result) {
3011 RHSValue.
getInt(), Result);
3022 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3023 "Operation not supported on vector types");
3027 QualType EltTy = VT->getElementType();
3034 "A vector result that isn't a vector OR uncalculated LValue");
3040 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3044 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3049 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3059 RHSElt.
getInt(), EltResult);
3065 ResultElements.emplace_back(EltResult);
3070 "Mismatched LHS/RHS/Result Type");
3071 APFloat LHSFloat = LHSElt.
getFloat();
3079 ResultElements.emplace_back(LHSFloat);
3083 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3091 unsigned TruncatedElements) {
3092 SubobjectDesignator &D = Result.Designator;
3095 if (TruncatedElements == D.Entries.size())
3097 assert(TruncatedElements >= D.MostDerivedPathLength &&
3098 "not casting to a derived class");
3104 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3108 if (isVirtualBaseClass(D.Entries[I]))
3114 D.Entries.resize(TruncatedElements);
3124 RL = &Info.Ctx.getASTRecordLayout(Derived);
3127 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3128 Obj.addDecl(Info, E,
Base,
false);
3137 if (!
Base->isVirtual())
3140 SubobjectDesignator &D = Obj.Designator;
3145 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
3151 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3153 Obj.addDecl(Info, E, BaseDecl,
true);
3161 PathI != PathE; ++PathI) {
3165 Type = (*PathI)->getType();
3177 llvm_unreachable(
"Class must be derived from the passed in base class!");
3192 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3196 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3197 LVal.addDecl(Info, E, FD);
3205 for (
const auto *
C : IFD->
chain())
3238 if (SOT == SizeOfType::SizeOf)
3239 Size = Info.Ctx.getTypeSizeInChars(
Type);
3241 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3258 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3264 int64_t Adjustment) {
3266 APSInt::get(Adjustment));
3281 LVal.Offset += SizeOfComponent;
3283 LVal.addComplex(Info, E, EltTy, Imag);
3297 const VarDecl *VD, CallStackFrame *Frame,
3298 unsigned Version,
APValue *&Result) {
3303 Result = Frame->getTemporary(VD, Version);
3307 if (!isa<ParmVarDecl>(VD)) {
3314 "missing value for local variable");
3315 if (Info.checkingPotentialConstantExpression())
3320 diag::note_unimplemented_constexpr_lambda_feature_ast)
3321 <<
"captures not currently allowed";
3328 if (Info.EvaluatingDecl ==
Base) {
3329 Result = Info.EvaluatingDeclValue;
3333 if (isa<ParmVarDecl>(VD)) {
3336 if (!Info.checkingPotentialConstantExpression() ||
3337 !Info.CurrentCall->Callee ||
3339 if (Info.getLangOpts().CPlusPlus11) {
3340 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3360 if (!Info.checkingPotentialConstantExpression()) {
3361 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3368 if (
Init->isValueDependent()) {
3375 if (!Info.checkingPotentialConstantExpression()) {
3376 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3377 ? diag::note_constexpr_ltor_non_constexpr
3378 : diag::note_constexpr_ltor_non_integral, 1)
3388 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3404 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3406 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3413 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3429 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3430 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3434 llvm_unreachable(
"base class missing from derived class's bases list");
3440 assert(!isa<SourceLocExpr>(Lit) &&
3441 "SourceLocExpr should have already been converted to a StringLiteral");
3444 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3446 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3447 assert(Index <= Str.size() &&
"Index too large");
3448 return APSInt::getUnsigned(Str.c_str()[Index]);
3451 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3452 Lit = PE->getFunctionName();
3455 Info.Ctx.getAsConstantArrayType(S->getType());
3456 assert(CAT &&
"string literal isn't an array");
3458 assert(CharType->
isIntegerType() &&
"unexpected character type");
3461 if (Index < S->getLength())
3462 Value = S->getCodeUnit(Index);
3474 AllocType.isNull() ? S->getType() : AllocType);
3475 assert(CAT &&
"string literal isn't an array");
3477 assert(CharType->
isIntegerType() &&
"unexpected character type");
3481 std::min(S->getLength(), Elts), Elts);
3484 if (Result.hasArrayFiller())
3486 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3487 Value = S->getCodeUnit(I);
3494 unsigned Size = Array.getArraySize();
3495 assert(Index < Size);
3498 unsigned OldElts = Array.getArrayInitializedElts();
3499 unsigned NewElts = std::max(Index+1, OldElts * 2);
3500 NewElts = std::min(Size, std::max(NewElts, 8u));
3504 for (
unsigned I = 0; I != OldElts; ++I)
3506 for (
unsigned I = OldElts; I != NewElts; ++I)
3510 Array.swap(NewValue);
3531 for (
auto *Field : RD->
fields())
3532 if (!Field->isUnnamedBitField() &&
3536 for (
auto &BaseSpec : RD->
bases())
3554 for (
auto *Field : RD->
fields()) {
3559 if (Field->isMutable() &&
3561 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3562 Info.Note(Field->getLocation(), diag::note_declared_at);
3570 for (
auto &BaseSpec : RD->
bases())
3580 bool MutableSubobject =
false) {
3585 switch (Info.IsEvaluatingDecl) {
3586 case EvalInfo::EvaluatingDeclKind::None:
3589 case EvalInfo::EvaluatingDeclKind::Ctor:
3591 if (Info.EvaluatingDecl ==
Base)
3596 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3597 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3598 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3601 case EvalInfo::EvaluatingDeclKind::Dtor:
3606 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3615 llvm_unreachable(
"unknown evaluating decl kind");
3620 return Info.CheckArraySize(
3629struct CompleteObject {
3637 CompleteObject() :
Value(nullptr) {}
3641 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3652 if (!Info.getLangOpts().CPlusPlus14)
3657 explicit operator bool()
const {
return !
Type.isNull(); }
3662 bool IsMutable =
false) {
3676template<
typename Sub
objectHandler>
3677typename SubobjectHandler::result_type
3679 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3682 return handler.failed();
3683 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3684 if (Info.getLangOpts().CPlusPlus11)
3685 Info.FFDiag(E, Sub.isOnePastTheEnd()
3686 ? diag::note_constexpr_access_past_end
3687 : diag::note_constexpr_access_unsized_array)
3688 << handler.AccessKind;
3691 return handler.failed();
3697 const FieldDecl *VolatileField =
nullptr;
3700 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3705 if (!Info.checkingPotentialConstantExpression())
3706 Info.FFDiag(E, diag::note_constexpr_access_uninit)
3709 return handler.failed();
3717 Info.isEvaluatingCtorDtor(
3720 ConstructionPhase::None) {
3730 if (Info.getLangOpts().CPlusPlus) {
3734 if (VolatileField) {
3737 Decl = VolatileField;
3738 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3740 Loc = VD->getLocation();
3744 if (
auto *E = Obj.Base.dyn_cast<
const Expr *>())
3747 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3748 << handler.AccessKind << DiagKind <<
Decl;
3749 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
3751 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3753 return handler.failed();
3761 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3763 return handler.failed();
3767 if (!handler.found(*O, ObjType))
3779 LastField =
nullptr;
3783 assert(CAT &&
"vla in literal type?");
3784 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3785 if (CAT->
getSize().ule(Index)) {
3788 if (Info.getLangOpts().CPlusPlus11)
3789 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3790 << handler.AccessKind;
3793 return handler.failed();
3800 else if (!
isRead(handler.AccessKind)) {
3802 return handler.failed();
3810 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3812 if (Info.getLangOpts().CPlusPlus11)
3813 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3814 << handler.AccessKind;
3817 return handler.failed();
3823 assert(I == N - 1 &&
"extracting subobject of scalar?");
3832 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3833 if (Field->isMutable() &&
3834 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
3835 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
3836 << handler.AccessKind << Field;
3837 Info.Note(Field->getLocation(), diag::note_declared_at);
3838 return handler.failed();
3847 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
3855 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
3856 << handler.AccessKind << Field << !UnionField << UnionField;
3857 return handler.failed();
3866 if (Field->getType().isVolatileQualified())
3867 VolatileField = Field;
3880struct ExtractSubobjectHandler {
3886 typedef bool result_type;
3887 bool failed() {
return false; }
3907 const CompleteObject &Obj,
3908 const SubobjectDesignator &Sub,
APValue &Result,
3911 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
3916struct ModifySubobjectHandler {
3921 typedef bool result_type;
3927 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3933 bool failed() {
return false; }
3935 if (!checkConst(SubobjType))
3938 Subobj.
swap(NewVal);
3942 if (!checkConst(SubobjType))
3944 if (!NewVal.
isInt()) {
3953 if (!checkConst(SubobjType))
3961const AccessKinds ModifySubobjectHandler::AccessKind;
3965 const CompleteObject &Obj,
3966 const SubobjectDesignator &Sub,
3968 ModifySubobjectHandler Handler = { Info, NewVal, E };
3975 const SubobjectDesignator &A,
3976 const SubobjectDesignator &B,
3977 bool &WasArrayIndex) {
3978 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
3979 for (; I != N; ++I) {
3983 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
3984 WasArrayIndex =
true;
3992 if (A.Entries[I].getAsBaseOrMember() !=
3993 B.Entries[I].getAsBaseOrMember()) {
3994 WasArrayIndex =
false;
3997 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
3999 ObjType = FD->getType();
4005 WasArrayIndex =
false;
4012 const SubobjectDesignator &A,
4013 const SubobjectDesignator &B) {
4014 if (A.Entries.size() != B.Entries.size())
4017 bool IsArray = A.MostDerivedIsArrayElement;
4018 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4027 return CommonLength >= A.Entries.size() - IsArray;
4034 if (LVal.InvalidBase) {
4036 return CompleteObject();
4040 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4041 return CompleteObject();
4044 CallStackFrame *Frame =
nullptr;
4046 if (LVal.getLValueCallIndex()) {
4047 std::tie(Frame, Depth) =
4048 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4050 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
4051 << AK << LVal.Base.is<
const ValueDecl*>();
4053 return CompleteObject();
4064 if (Info.getLangOpts().CPlusPlus)
4065 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4069 return CompleteObject();
4074 QualType BaseType = getType(LVal.Base);
4076 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4080 BaseVal = Info.EvaluatingDeclValue;
4083 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4086 Info.FFDiag(E, diag::note_constexpr_modify_global);
4087 return CompleteObject();
4091 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4093 return CompleteObject();
4095 return CompleteObject(LVal.Base, &
V, GD->getType());
4099 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4101 Info.FFDiag(E, diag::note_constexpr_modify_global);
4102 return CompleteObject();
4104 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4109 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4111 Info.FFDiag(E, diag::note_constexpr_modify_global);
4112 return CompleteObject();
4114 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4125 const VarDecl *VD = dyn_cast<VarDecl>(D);
4132 return CompleteObject();
4135 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4136 bool ConstexprVar =
false;
4137 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4138 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4144 if (IsAccess && isa<ParmVarDecl>(VD)) {
4148 }
else if (Info.getLangOpts().CPlusPlus14 &&
4155 Info.FFDiag(E, diag::note_constexpr_modify_global);
4156 return CompleteObject();
4159 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4161 return CompleteObject();
4165 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4166 if (Info.getLangOpts().CPlusPlus) {
4167 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4168 Info.Note(VD->
getLocation(), diag::note_declared_at);
4172 return CompleteObject();
4174 }
else if (!IsAccess) {
4175 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4176 }
else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4179 }
else if (IsConstant) {
4183 if (Info.getLangOpts().CPlusPlus) {
4184 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4185 ? diag::note_constexpr_ltor_non_constexpr
4186 : diag::note_constexpr_ltor_non_integral, 1)
4188 Info.Note(VD->
getLocation(), diag::note_declared_at);
4194 if (Info.getLangOpts().CPlusPlus) {
4195 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4196 ? diag::note_constexpr_ltor_non_constexpr
4197 : diag::note_constexpr_ltor_non_integral, 1)
4199 Info.Note(VD->
getLocation(), diag::note_declared_at);
4203 return CompleteObject();
4208 return CompleteObject();
4210 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4212 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4213 return CompleteObject();
4215 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4216 LVal.Base.getDynamicAllocType());
4222 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4223 assert(MTE->getStorageDuration() ==
SD_Static &&
4224 "should have a frame for a non-global materialized temporary");
4251 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4254 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4255 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4256 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4257 return CompleteObject();
4260 BaseVal = MTE->getOrCreateValue(
false);
4261 assert(BaseVal &&
"got reference to unevaluated temporary");
4264 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4267 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4270 Info.Ctx.getLValueReferenceType(LValType));
4272 return CompleteObject();
4275 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4276 assert(BaseVal &&
"missing value for temporary");
4287 unsigned VisibleDepth = Depth;
4288 if (llvm::isa_and_nonnull<ParmVarDecl>(
4289 LVal.Base.dyn_cast<
const ValueDecl *>()))
4291 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4292 Info.EvalStatus.HasSideEffects) ||
4293 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4294 return CompleteObject();
4296 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4315 const LValue &LVal,
APValue &RVal,
4316 bool WantObjectRepresentation =
false) {
4317 if (LVal.Designator.Invalid)
4326 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4331 if (
Type.isVolatileQualified()) {
4337 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
4357 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4362 CompleteObject LitObj(LVal.Base, &Lit,
Base->getType());
4364 }
else if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4367 assert(LVal.Designator.Entries.size() <= 1 &&
4368 "Can only read characters from string literals");
4369 if (LVal.Designator.Entries.empty()) {
4376 if (LVal.Designator.isOnePastTheEnd()) {
4377 if (Info.getLangOpts().CPlusPlus11)
4378 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4383 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4390 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4396 if (LVal.Designator.Invalid)
4399 if (!Info.getLangOpts().CPlusPlus14) {
4409struct CompoundAssignSubobjectHandler {
4418 typedef bool result_type;
4423 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4429 bool failed() {
return false; }
4433 return found(Subobj.
getInt(), SubobjType);
4435 return found(Subobj.
getFloat(), SubobjType);
4442 return foundPointer(Subobj, SubobjType);
4444 return foundVector(Subobj, SubobjType);
4446 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4458 if (!checkConst(SubobjType))
4469 if (!checkConst(SubobjType))
4488 Info.Ctx.getLangOpts());
4491 PromotedLHSType, FValue) &&
4501 return checkConst(SubobjType) &&
4508 if (!checkConst(SubobjType))
4516 (Opcode != BO_Add && Opcode != BO_Sub)) {
4522 if (Opcode == BO_Sub)
4526 LVal.setFrom(Info.Ctx, Subobj);
4529 LVal.moveInto(Subobj);
4535const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4540 const LValue &LVal,
QualType LValType,
4544 if (LVal.Designator.Invalid)
4547 if (!Info.getLangOpts().CPlusPlus14) {
4553 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
4555 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4559struct IncDecSubobjectHandler {
4565 typedef bool result_type;
4570 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4576 bool failed() {
return false; }
4587 return found(Subobj.
getInt(), SubobjType);
4589 return found(Subobj.
getFloat(), SubobjType);
4599 return foundPointer(Subobj, SubobjType);
4607 if (!checkConst(SubobjType))
4629 bool WasNegative =
Value.isNegative();
4641 unsigned BitWidth =
Value.getBitWidth();
4642 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4643 ActualValue.setBit(BitWidth);
4650 if (!checkConst(SubobjType))
4657 APFloat::opStatus St;
4659 St =
Value.add(One, RM);
4661 St =
Value.subtract(One, RM);
4665 if (!checkConst(SubobjType))
4677 LVal.setFrom(Info.Ctx, Subobj);
4681 LVal.moveInto(Subobj);
4690 if (LVal.Designator.Invalid)
4693 if (!Info.getLangOpts().CPlusPlus14) {
4700 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(E), AK, Old};
4701 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4707 if (Object->getType()->isPointerType() && Object->isPRValue())
4710 if (Object->isGLValue())
4713 if (Object->getType()->isLiteralType(Info.Ctx))
4716 if (Object->getType()->isRecordType() && Object->isPRValue())
4719 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4738 bool IncludeMember =
true) {
4745 if (!MemPtr.getDecl()) {
4751 if (MemPtr.isDerivedMember()) {
4755 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
4756 LV.Designator.Entries.size()) {
4760 unsigned PathLengthToMember =
4761 LV.Designator.Entries.size() - MemPtr.Path.size();
4762 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
4764 LV.Designator.Entries[PathLengthToMember + I]);
4774 PathLengthToMember))
4776 }
else if (!MemPtr.Path.empty()) {
4778 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
4779 MemPtr.Path.size() + IncludeMember);
4785 assert(RD &&
"member pointer access on non-class-type expression");
4787 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
4795 MemPtr.getContainingRecord()))
4800 if (IncludeMember) {
4801 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
4805 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
4809 llvm_unreachable(
"can't construct reference to bound member function");
4813 return MemPtr.getDecl();
4819 bool IncludeMember =
true) {
4823 if (Info.noteFailure()) {
4831 BO->
getRHS(), IncludeMember);
4838 SubobjectDesignator &D = Result.Designator;
4839 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
4847 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
4848 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4849 << D.MostDerivedType << TargetQT;
4855 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
4858 if (NewEntriesSize == D.MostDerivedPathLength)
4859 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
4861 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
4863 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4864 << D.MostDerivedType << TargetQT;
4878 if (!Result.isAbsent())
4882 if (RD->isInvalidDecl()) {
4886 if (RD->isUnion()) {
4891 std::distance(RD->field_begin(), RD->field_end()));
4895 End = RD->bases_end();
4896 I != End; ++I, ++Index)
4900 for (
const auto *I : RD->fields()) {
4901 if (I->isUnnamedBitField())
4904 I->getType(), Result.getStructField(I->getFieldIndex()));
4912 if (Result.hasArrayFiller())
4924enum EvalStmtResult {
4948 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
4949 ScopeKind::Block, Result);
4954 return Info.noteSideEffect();
4973 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
4977 for (
auto *BD : DD->bindings())
4978 if (
auto *VD = BD->getHoldingVar())
4986 if (Info.noteSideEffect())
4988 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
4989 "reach invalid code path.");
4995 const Expr *Cond,
bool &Result) {
4998 FullExpressionRAII
Scope(Info);
5003 return Scope.destroy();
5016struct TempVersionRAII {
5017 CallStackFrame &Frame;
5019 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5020 Frame.pushTempVersion();
5023 ~TempVersionRAII() {
5024 Frame.popTempVersion();
5038 BlockScopeRAII
Scope(Info);
5040 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5041 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5046 return ESR_Succeeded;
5049 return ESR_Continue;
5052 case ESR_CaseNotFound:
5055 llvm_unreachable(
"Invalid EvalStmtResult!");
5061 BlockScopeRAII
Scope(Info);
5068 if (ESR != ESR_Succeeded) {
5069 if (ESR != ESR_Failed && !
Scope.destroy())
5075 FullExpressionRAII CondScope(Info);
5087 if (!CondScope.destroy())
5096 if (isa<DefaultStmt>(SC)) {
5101 const CaseStmt *CS = cast<CaseStmt>(SC);
5112 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5116 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5121 return ESR_Succeeded;
5127 case ESR_CaseNotFound:
5131 diag::note_constexpr_stmt_expr_unsupported);
5134 llvm_unreachable(
"Invalid EvalStmtResult!");
5144 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5154 if (!Info.nextStep(S))
5160 switch (S->getStmtClass()) {
5161 case Stmt::CompoundStmtClass:
5165 case Stmt::LabelStmtClass:
5166 case Stmt::AttributedStmtClass:
5167 case Stmt::DoStmtClass:
5170 case Stmt::CaseStmtClass:
5171 case Stmt::DefaultStmtClass:
5176 case Stmt::IfStmtClass: {
5179 const IfStmt *IS = cast<IfStmt>(S);
5183 BlockScopeRAII
Scope(Info);
5189 if (ESR != ESR_CaseNotFound) {
5190 assert(ESR != ESR_Succeeded);
5201 if (ESR == ESR_Failed)
5203 if (ESR != ESR_CaseNotFound)
5204 return Scope.destroy() ? ESR : ESR_Failed;
5206 return ESR_CaseNotFound;
5209 if (ESR == ESR_Failed)
5211 if (ESR != ESR_CaseNotFound)
5212 return Scope.destroy() ? ESR : ESR_Failed;
5213 return ESR_CaseNotFound;
5216 case Stmt::WhileStmtClass: {
5217 EvalStmtResult ESR =
5219 if (ESR != ESR_Continue)
5224 case Stmt::ForStmtClass: {
5225 const ForStmt *FS = cast<ForStmt>(S);
5226 BlockScopeRAII
Scope(Info);
5230 if (
const Stmt *
Init = FS->getInit()) {
5232 if (ESR != ESR_CaseNotFound) {
5233 assert(ESR != ESR_Succeeded);
5238 EvalStmtResult ESR =
5240 if (ESR != ESR_Continue)
5242 if (
const auto *Inc = FS->getInc()) {
5243 if (Inc->isValueDependent()) {
5247 FullExpressionRAII IncScope(Info);
5255 case Stmt::DeclStmtClass: {
5258 const DeclStmt *DS = cast<DeclStmt>(S);
5259 for (
const auto *D : DS->
decls()) {
5260 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5263 if (VD->hasLocalStorage() && !VD->getInit())
5271 return ESR_CaseNotFound;
5275 return ESR_CaseNotFound;
5279 switch (S->getStmtClass()) {
5281 if (
const Expr *E = dyn_cast<Expr>(S)) {
5290 FullExpressionRAII
Scope(Info);
5294 return ESR_Succeeded;
5297 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5300 case Stmt::NullStmtClass:
5301 return ESR_Succeeded;
5303 case Stmt::DeclStmtClass: {
5304 const DeclStmt *DS = cast<DeclStmt>(S);
5305 for (
const auto *D : DS->
decls()) {
5306 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5310 FullExpressionRAII
Scope(Info);
5313 if (!
Scope.destroy())
5316 return ESR_Succeeded;
5319 case Stmt::ReturnStmtClass: {
5320 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5321 FullExpressionRAII
Scope(Info);
5330 :
Evaluate(Result.Value, Info, RetExpr)))
5332 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5335 case Stmt::CompoundStmtClass: {
5336 BlockScopeRAII
Scope(Info);
5339 for (
const auto *BI : CS->
body()) {
5340 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5341 if (ESR == ESR_Succeeded)
5343 else if (ESR != ESR_CaseNotFound) {
5344 if (ESR != ESR_Failed && !
Scope.destroy())
5350 return ESR_CaseNotFound;
5351 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5354 case Stmt::IfStmtClass: {
5355 const IfStmt *IS = cast<IfStmt>(S);
5358 BlockScopeRAII
Scope(Info);
5361 if (ESR != ESR_Succeeded) {
5362 if (ESR != ESR_Failed && !
Scope.destroy())
5372 if (!Info.InConstantContext)
5379 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5380 if (ESR != ESR_Succeeded) {
5381 if (ESR != ESR_Failed && !
Scope.destroy())
5386 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5389 case Stmt::WhileStmtClass: {
5390 const WhileStmt *WS = cast<WhileStmt>(S);
5392 BlockScopeRAII
Scope(Info);
5401 if (ESR != ESR_Continue) {
5402 if (ESR != ESR_Failed && !
Scope.destroy())
5406 if (!
Scope.destroy())
5409 return ESR_Succeeded;
5412 case Stmt::DoStmtClass: {
5413 const DoStmt *DS = cast<DoStmt>(S);
5417 if (ESR != ESR_Continue)
5426 FullExpressionRAII CondScope(Info);
5428 !CondScope.destroy())
5431 return ESR_Succeeded;
5434 case Stmt::ForStmtClass: {
5435 const ForStmt *FS = cast<ForStmt>(S);
5436 BlockScopeRAII ForScope(Info);
5437 if (FS->getInit()) {
5438 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5439 if (ESR != ESR_Succeeded) {
5440 if (ESR != ESR_Failed && !ForScope.destroy())
5446 BlockScopeRAII IterScope(Info);
5447 bool Continue =
true;
5448 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5449 FS->getCond(), Continue))
5455 if (ESR != ESR_Continue) {
5456 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5461 if (
const auto *Inc = FS->getInc()) {
5462 if (Inc->isValueDependent()) {
5466 FullExpressionRAII IncScope(Info);
5472 if (!IterScope.destroy())
5475 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5478 case Stmt::CXXForRangeStmtClass: {
5480 BlockScopeRAII
Scope(Info);
5483 if (FS->getInit()) {
5484 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5485 if (ESR != ESR_Succeeded) {
5486 if (ESR != ESR_Failed && !
Scope.destroy())
5493 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5494 if (ESR != ESR_Succeeded) {
5495 if (ESR != ESR_Failed && !
Scope.destroy())
5502 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5507 if (ESR != ESR_Succeeded) {
5508 if (ESR != ESR_Failed && !
Scope.destroy())
5513 if (ESR != ESR_Succeeded) {
5514 if (ESR != ESR_Failed && !
Scope.destroy())
5522 if (FS->getCond()->isValueDependent()) {
5527 bool Continue =
true;
5528 FullExpressionRAII CondExpr(Info);
5536 BlockScopeRAII InnerScope(Info);
5537 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5538 if (ESR != ESR_Succeeded) {
5539 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5546 if (ESR != ESR_Continue) {
5547 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5551 if (FS->getInc()->isValueDependent()) {
5560 if (!InnerScope.destroy())
5564 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5567 case Stmt::SwitchStmtClass:
5570 case Stmt::ContinueStmtClass:
5571 return ESR_Continue;
5573 case Stmt::BreakStmtClass:
5576 case Stmt::LabelStmtClass:
5577 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5579 case Stmt::AttributedStmtClass: {
5580 const auto *AS = cast<AttributedStmt>(S);
5581 const auto *SS = AS->getSubStmt();
5582 MSConstexprContextRAII ConstexprContext(
5583 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5584 isa<ReturnStmt>(SS));
5586 auto LO = Info.getCtx().getLangOpts();
5587 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5588 for (
auto *
Attr : AS->getAttrs()) {
5589 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5593 auto *Assumption = AA->getAssumption();
5594 if (Assumption->isValueDependent())
5597 if (Assumption->HasSideEffects(Info.getCtx()))
5604 Info.CCEDiag(Assumption->getExprLoc(),
5605 diag::note_constexpr_assumption_failed);
5614 case Stmt::CaseStmtClass:
5615 case Stmt::DefaultStmtClass:
5616 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5617 case Stmt::CXXTryStmtClass:
5619 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5629 bool IsValueInitialization) {
5636 if (!CD->
isConstexpr() && !IsValueInitialization) {
5637 if (Info.getLangOpts().CPlusPlus11) {
5640 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
5642 Info.Note(CD->
getLocation(), diag::note_declared_at);
5644 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
5658 if (Info.checkingPotentialConstantExpression() && !
Definition &&
5666 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5673 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
5675 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
5678 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5684 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
5688 if (Info.getLangOpts().CPlusPlus11) {
5693 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
5694 if (CD && CD->isInheritingConstructor()) {
5695 auto *Inherited = CD->getInheritedConstructor().getConstructor();
5696 if (!Inherited->isConstexpr())
5697 DiagDecl = CD = Inherited;
5703 if (CD && CD->isInheritingConstructor())
5704 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
5705 << CD->getInheritedConstructor().getConstructor()->
getParent();
5707 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
5709 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
5711 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5717struct CheckDynamicTypeHandler {
5719 typedef bool result_type;
5720 bool failed() {
return false; }
5723 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
5731 if (This.Designator.Invalid)
5743 if (This.Designator.isOnePastTheEnd() ||
5744 This.Designator.isMostDerivedAnUnsizedArray()) {
5745 Info.FFDiag(E, This.Designator.isOnePastTheEnd()
5746 ? diag::note_constexpr_access_past_end
5747 : diag::note_constexpr_access_unsized_array)
5750 }
else if (Polymorphic) {
5756 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
5757 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
5764 CheckDynamicTypeHandler Handler{AK};
5765 return Obj &&
findSubobject(Info, E, Obj, This.Designator, Handler);
5787 unsigned PathLength) {
5788 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
5789 Designator.Entries.size() &&
"invalid path length");
5790 return (PathLength ==
Designator.MostDerivedPathLength)
5791 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
5792 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
5804 return std::nullopt;
5813 This.Designator.MostDerivedType->getAsCXXRecordDecl();
5816 return std::nullopt;
5824 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
5825 PathLength <= Path.size(); ++PathLength) {
5826 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
5827 Path.slice(0, PathLength))) {
5828 case ConstructionPhase::Bases:
5829 case ConstructionPhase::DestroyingBases:
5834 case ConstructionPhase::None:
5835 case ConstructionPhase::AfterBases:
5836 case ConstructionPhase::AfterFields:
5837 case ConstructionPhase::Destroying:
5849 return std::nullopt;
5867 unsigned PathLength = DynType->PathLength;
5868 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
5881 if (Callee->isPureVirtual()) {
5882 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
5883 Info.Note(Callee->getLocation(), diag::note_declared_at);
5889 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
5891 CovariantAdjustmentPath.push_back(Callee->getReturnType());
5892 for (
unsigned CovariantPathLength = PathLength + 1;
5893 CovariantPathLength != This.Designator.Entries.size();
5894 ++CovariantPathLength) {
5899 if (Next && !Info.Ctx.hasSameUnqualifiedType(
5900 Next->getReturnType(), CovariantAdjustmentPath.back()))
5901 CovariantAdjustmentPath.push_back(Next->getReturnType());
5903 if (!Info.Ctx.hasSameUnqualifiedType(Found->
getReturnType(),
5904 CovariantAdjustmentPath.back()))
5921 assert(Result.isLValue() &&
5922 "unexpected kind of APValue for covariant return");
5923 if (Result.isNullPointer())
5927 LVal.setFrom(Info.Ctx, Result);
5929 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
5930 for (
unsigned I = 1; I != Path.size(); ++I) {
5931 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
5932 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
5933 if (OldClass != NewClass &&
5936 OldClass = NewClass;
5939 LVal.moveInto(Result);
5948 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
5950 return BaseSpec.getAccessSpecifier() ==
AS_public;
5952 llvm_unreachable(
"Base is not a direct base of Derived");
5962 SubobjectDesignator &D = Ptr.Designator;
5968 if (Ptr.isNullPointer() && !E->
isGLValue())
5974 std::optional<DynamicType> DynType =
5986 assert(
C &&
"dynamic_cast target is not void pointer nor class");
5987 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(
C));
5994 Ptr.setNull(Info.Ctx, E->
getType());
6001 DynType->Type->isDerivedFrom(
C)))
6003 else if (!Paths || Paths->begin() == Paths->end())
6005 else if (Paths->isAmbiguous(CQT))
6008 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6011 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6012 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6013 << Info.Ctx.getRecordType(DynType->Type)
6021 for (
int PathLength = Ptr.Designator.Entries.size();
6022 PathLength >= (
int)DynType->PathLength; --PathLength) {
6027 if (PathLength > (
int)DynType->PathLength &&
6030 return RuntimeCheckFailed(
nullptr);
6037 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6050 return RuntimeCheckFailed(&Paths);
6054struct StartLifetimeOfUnionMemberHandler {
6056 const Expr *LHSExpr;
6059 bool Failed =
false;
6062 typedef bool result_type;
6063 bool failed() {
return Failed; }
6079 }
else if (DuringInit) {
6083 Info.FFDiag(LHSExpr,
6084 diag::note_constexpr_union_member_change_during_init);
6093 llvm_unreachable(
"wrong value kind for union object");
6096 llvm_unreachable(
"wrong value kind for union object");
6101const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6108 const Expr *LHSExpr,
6109 const LValue &LHS) {
6110 if (LHS.InvalidBase || LHS.Designator.Invalid)
6116 unsigned PathLength = LHS.Designator.Entries.size();
6117 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6119 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6120 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6123 if (!FD || FD->getType()->isReferenceType())
6127 if (FD->getParent()->isUnion()) {
6132 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6133 if (!RD || RD->hasTrivialDefaultConstructor())
6134 UnionPathLengths.push_back({PathLength - 1, FD});
6140 LHS.Designator.Entries[PathLength]
6141 .getAsBaseOrMember().getPointer()));
6145 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6147 auto *
Base = ASE->getBase()->IgnoreImplicit();
6148 if (!
Base->getType()->isArrayType())
6154 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6157 if (ICE->getCastKind() == CK_NoOp)
6159 if (ICE->getCastKind() != CK_DerivedToBase &&
6160 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6164 if (Elt->isVirtual()) {
6173 LHS.Designator.Entries[PathLength]
6174 .getAsBaseOrMember().getPointer()));
6184 if (UnionPathLengths.empty())
6189 CompleteObject Obj =
6193 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6194 llvm::reverse(UnionPathLengths)) {
6196 SubobjectDesignator D = LHS.Designator;
6197 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6199 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6200 ConstructionPhase::AfterBases;
6201 StartLifetimeOfUnionMemberHandler StartLifetime{
6202 Info, LHSExpr, LengthAndField.second, DuringInit};
6211 CallRef
Call, EvalInfo &Info,
6219 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6220 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6221 ScopeKind::Call, LV);
6227 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6228 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6238 bool RightToLeft =
false) {
6240 llvm::SmallBitVector ForbiddenNullArgs;
6241 if (Callee->hasAttr<NonNullAttr>()) {
6242 ForbiddenNullArgs.resize(Args.size());
6243 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6244 if (!
Attr->args_size()) {
6245 ForbiddenNullArgs.set();
6248 for (
auto Idx :
Attr->args()) {
6249 unsigned ASTIdx = Idx.getASTIndex();
6250 if (ASTIdx >= Args.size())
6252 ForbiddenNullArgs[ASTIdx] =
true;
6256 for (
unsigned I = 0; I < Args.size(); I++) {
6257 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6259 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6260 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6264 if (!Info.noteFailure())
6276 bool CopyObjectRepresentation) {
6278 CallStackFrame *Frame = Info.CurrentCall;
6279 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6287 RefLValue.setFrom(Info.Ctx, *RefValue);
6290 CopyObjectRepresentation);
6297 CallRef
Call,
const Stmt *Body, EvalInfo &Info,
6298 APValue &Result,
const LValue *ResultSlot) {
6299 if (!Info.CheckCallLimit(CallLoc))
6324 This->moveInto(Result);
6333 if (!Info.checkingPotentialConstantExpression())
6335 Frame.LambdaThisCaptureField);
6340 if (ESR == ESR_Succeeded) {
6341 if (Callee->getReturnType()->isVoidType())
6343 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6345 return ESR == ESR_Returned;
6352 EvalInfo &Info,
APValue &Result) {
6354 if (!Info.CheckCallLimit(CallLoc))
6359 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6363 EvalInfo::EvaluatingConstructorRAII EvalObj(
6365 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
6377 if ((*I)->getInit()->isValueDependent()) {
6381 FullExpressionRAII InitScope(Info);
6383 !InitScope.destroy())
6406 if (!Result.hasValue()) {
6419 BlockScopeRAII LifetimeExtendedScope(Info);
6422 unsigned BasesSeen = 0;
6427 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
6432 assert(Indirect &&
"fields out of order?");
6438 assert(FieldIt != RD->
field_end() &&
"missing field?");
6439 if (!FieldIt->isUnnamedBitField())
6442 Result.getStructField(FieldIt->getFieldIndex()));
6447 LValue Subobject = This;
6448 LValue SubobjectParent = This;
6453 if (I->isBaseInitializer()) {
6454 QualType BaseType(I->getBaseClass(), 0);
6458 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6459 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6460 "base class initializers not in expected order");
6466 Value = &Result.getStructBase(BasesSeen++);
6467 }
else if ((FD = I->getMember())) {
6472 Value = &Result.getUnionValue();
6474 SkipToField(FD,
false);
6480 auto IndirectFieldChain = IFD->chain();
6481 for (
auto *
C : IndirectFieldChain) {
6482 FD = cast<FieldDecl>(
C);
6490 (
Value->isUnion() &&
Value->getUnionField() != FD)) {
6502 if (
C == IndirectFieldChain.back())
6503 SubobjectParent = Subobject;
6509 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6510 SkipToField(FD,
true);
6515 llvm_unreachable(
"unknown base initializer kind");
6522 if (
Init->isValueDependent()) {
6526 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6527 isa<CXXDefaultInitExpr>(
Init));
6528 FullExpressionRAII InitScope(Info);
6534 if (!Info.noteFailure())
6542 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6543 EvalObj.finishedConstructingBases();
6548 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6549 if (!FieldIt->isUnnamedBitField())
6552 Result.getStructField(FieldIt->getFieldIndex()));
6556 EvalObj.finishedConstructingFields();
6560 LifetimeExtendedScope.destroy();
6566 EvalInfo &Info,
APValue &Result) {
6567 CallScopeRAII CallScope(Info);
6573 CallScope.destroy();
6585 This.moveInto(Printable);
6587 diag::note_constexpr_destroy_out_of_lifetime)
6588 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6604 LValue ElemLV = This;
6605 ElemLV.addArray(Info, &LocE, CAT);
6612 if (Size && Size >
Value.getArrayInitializedElts())
6615 for (; Size != 0; --Size) {
6616 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
6629 if (
T.isDestructedType()) {
6631 diag::note_constexpr_unsupported_destruction)
6641 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
6666 if (!Info.CheckCallLimit(CallRange.
getBegin()))
6675 CallStackFrame Frame(Info, CallRange,
Definition, &This,
nullptr,
6680 EvalInfo::EvaluatingDestructorRAII EvalObj(
6682 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
6683 if (!EvalObj.DidInsert) {
6690 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
6710 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
6711 if (FD->isUnnamedBitField())
6714 LValue Subobject = This;
6718 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
6725 EvalObj.startedDestroyingBases();
6732 LValue Subobject = This;
6737 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
6742 assert(BasesLeft == 0 &&
"NumBases was wrong?");
6750struct DestroyObjectHandler {
6756 typedef bool result_type;
6757 bool failed() {
return false; }
6763 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
6767 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
6776 const LValue &This,
QualType ThisType) {
6778 DestroyObjectHandler Handler = {Info, E, This,
AK_Destroy};
6779 return Obj &&
findSubobject(Info, E, Obj, This.Designator, Handler);
6788 if (Info.EvalStatus.HasSideEffects)
6799 if (Info.checkingPotentialConstantExpression() ||
6800 Info.SpeculativeEvaluationDepth)
6804 auto Caller = Info.getStdAllocatorCaller(
"allocate");
6806 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
6807 ? diag::note_constexpr_new_untyped
6808 : diag::note_constexpr_new);
6812 QualType ElemType = Caller.ElemType;
6815 diag::note_constexpr_new_not_complete_object_type)
6823 bool IsNothrow =
false;
6824 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
6832 APInt Size, Remainder;
6833 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
6834 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
6835 if (Remainder != 0) {
6837 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
6838 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
6842 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
6843 Size.getZExtValue(), !IsNothrow)) {
6845 Result.setNull(Info.Ctx, E->
getType());
6851 QualType AllocType = Info.Ctx.getConstantArrayType(
6852 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
6853 APValue *Val = Info.createHeapAlloc(E, AllocType, Result);
6855 Result.addArray(Info, E, cast<ConstantArrayType>(AllocType));
6862 return DD->isVirtual();
6869 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
6880 DynAlloc::Kind DeallocKind) {
6881 auto PointerAsString = [&] {
6882 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
6887 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
6888 << PointerAsString();
6891 return std::nullopt;
6894 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
6896 Info.FFDiag(E, diag::note_constexpr_double_delete);
6897 return std::nullopt;
6900 if (DeallocKind != (*Alloc)->getKind()) {
6902 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
6903 << DeallocKind << (*Alloc)->getKind() << AllocType;
6905 return std::nullopt;
6908 bool Subobject =
false;
6909 if (DeallocKind == DynAlloc::New) {
6910 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
6911 Pointer.Designator.isOnePastTheEnd();
6913 Subobject =
Pointer.Designator.Entries.size() != 1 ||
6914 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
6917 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
6918 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
6919 return std::nullopt;
6927 if (Info.checkingPotentialConstantExpression() ||
6928 Info.SpeculativeEvaluationDepth)
6932 if (!Info.getStdAllocatorCaller(
"deallocate")) {
6940 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
6943 if (
Pointer.Designator.Invalid)
6948 if (
Pointer.isNullPointer()) {
6949 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
6965class BitCastBuffer {
6973 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
6974 "Need at least 8 bit unsigned char");
6976 bool TargetIsLittleEndian;
6979 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
6980 : Bytes(Width.getQuantity()),
6981 TargetIsLittleEndian(TargetIsLittleEndian) {}
6985 for (
CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
6988 if (!Bytes[I.getQuantity()])
6990 Output.push_back(*Bytes[I.getQuantity()]);
6992 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
6993 std::reverse(Output.begin(), Output.end());
6998 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
6999 std::reverse(Input.begin(), Input.end());
7002 for (
unsigned char Byte : Input) {
7003 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7004 Bytes[Offset.getQuantity() + Index] = Byte;
7009 size_t size() {
return Bytes.size(); }
7014class APValueToBufferConverter {
7016 BitCastBuffer Buffer;
7019 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7022 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7031 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7044 return visitInt(Val.
getInt(), Ty, Offset);
7046 return visitFloat(Val.
getFloat(), Ty, Offset);
7048 return visitArray(Val, Ty, Offset);
7050 return visitRecord(Val, Ty, Offset);
7052 return visitVector(Val, Ty, Offset);
7063 diag::note_constexpr_bit_cast_unsupported_type)
7069 llvm_unreachable(
"LValue subobject in bit_cast?");
7071 llvm_unreachable(
"Unhandled APValue::ValueKind");
7079 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7080 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7091 unsigned FieldIdx = 0;
7093 if (FD->isBitField()) {
7095 diag::note_constexpr_bit_cast_unsupported_bitfield);
7101 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7102 "only bit-fields can have sub-char alignment");
7104 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7124 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7126 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7133 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7134 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7149 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7155 diag::note_constexpr_bit_cast_invalid_vector)
7157 << Info.Ctx.getCharWidth();
7161 if (EltTy->isRealFloatingType() && &Info.Ctx.getFloatTypeSemantics(EltTy) ==
7162 &APFloat::x87DoubleExtended()) {
7167 diag::note_constexpr_bit_cast_unsupported_type)
7181 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7183 llvm::APInt Res = llvm::APInt::getZero(NElts);
7184 for (
unsigned I = 0; I < NElts; ++I) {
7186 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7187 "bool vector element must be 1-bit unsigned integer!");
7189 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7193 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7194 Buffer.writeObject(Offset, Bytes);
7198 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7199 for (
unsigned I = 0; I < NElts; ++I) {
7200 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7209 APSInt AdjustedVal = Val;
7210 unsigned Width = AdjustedVal.getBitWidth();
7212 Width = Info.Ctx.getTypeSize(Ty);
7213 AdjustedVal = AdjustedVal.extend(Width);
7217 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7218 Buffer.writeObject(Offset, Bytes);
7223 APSInt AsInt(Val.bitcastToAPInt());
7224 return visitInt(AsInt, Ty, Offset);
7228 static std::optional<BitCastBuffer>
7231 APValueToBufferConverter Converter(Info, DstSize, BCE);
7233 return std::nullopt;
7234 return Converter.Buffer;
7239class BufferToAPValueConverter {
7241 const BitCastBuffer &Buffer;
7244 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7246 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7251 std::nullopt_t unsupportedType(
QualType Ty) {
7253 diag::note_constexpr_bit_cast_unsupported_type)
7255 return std::nullopt;
7258 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7260 diag::note_constexpr_bit_cast_unrepresentable_value)
7262 return std::nullopt;
7266 const EnumType *EnumSugar =
nullptr) {
7280 const llvm::fltSemantics &Semantics =
7281 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7282 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7283 assert(NumBits % 8 == 0);
7290 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7293 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7297 if (!IsStdByte && !IsUChar) {
7298 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7300 diag::note_constexpr_bit_cast_indet_dest)
7301 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7302 return std::nullopt;
7308 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7309 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7314 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7315 if (IntWidth != Val.getBitWidth()) {
7316 APSInt Truncated = Val.trunc(IntWidth);
7317 if (Truncated.extend(Val.getBitWidth()) != Val)
7318 return unrepresentableValue(
QualType(
T, 0), Val);
7326 const llvm::fltSemantics &Semantics =
7327 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7338 unsigned NumBases = 0;
7339 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7340 NumBases = CXXRD->getNumBases();
7346 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7347 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7351 std::optional<APValue> SubObj = visitType(
7354 return std::nullopt;
7355 ResultVal.getStructBase(I) = *SubObj;
7360 unsigned FieldIdx = 0;
7364 if (FD->isBitField()) {
7366 diag::note_constexpr_bit_cast_unsupported_bitfield);
7367 return std::nullopt;
7371 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7377 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7379 return std::nullopt;
7380 ResultVal.getStructField(FieldIdx) = *SubObj;
7389 assert(!RepresentationType.
isNull() &&
7390 "enum forward decl should be caught by Sema");
7391 const auto *AsBuiltin =
7395 return visit(AsBuiltin, Offset, Ty);
7403 for (
size_t I = 0; I !=
Size; ++I) {
7404 std::optional<APValue> ElementValue =
7407 return std::nullopt;
7408 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7420 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7426 diag::note_constexpr_bit_cast_invalid_vector)
7427 <<
QualType(VTy, 0) << EltSize << NElts << Info.Ctx.getCharWidth();
7428 return std::nullopt;
7432 &APFloat::x87DoubleExtended()) {
7437 diag::note_constexpr_bit_cast_unsupported_type)
7439 return std::nullopt;
7443 Elts.reserve(NElts);
7453 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7456 Bytes.reserve(NElts / 8);
7458 return std::nullopt;
7460 APSInt SValInt(NElts,
true);
7461 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7463 for (
unsigned I = 0; I < NElts; ++I) {
7465 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7472 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7473 for (
unsigned I = 0; I < NElts; ++I) {
7474 std::optional<APValue> EltValue =
7475 visitType(EltTy, Offset + I * EltSizeChars);
7477 return std::nullopt;
7478 Elts.push_back(std::move(*EltValue));
7482 return APValue(Elts.data(), Elts.size());
7485 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7486 return unsupportedType(
QualType(Ty, 0));
7493#define TYPE(Class, Base) \
7495 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7496#define ABSTRACT_TYPE(Class, Base)
7497#define NON_CANONICAL_TYPE(Class, Base) \
7499 llvm_unreachable("non-canonical type should be impossible!");
7500#define DEPENDENT_TYPE(Class, Base) \
7503 "dependent types aren't supported in the constant evaluator!");
7504#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7506 llvm_unreachable("either dependent or not canonical!");
7507#include "clang/AST/TypeNodes.inc"
7509 llvm_unreachable(
"Unhandled Type::TypeClass");
7514 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7516 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7521static bool checkBitCastConstexprEligibilityType(
SourceLocation Loc,
7524 bool CheckingDest) {
7527 auto diag = [&](
int Reason) {
7529 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
7530 << CheckingDest << (Reason == 4) << Reason;
7535 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7536 << NoteTy << Construct << Ty;
7550 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7552 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
7557 if (FD->getType()->isReferenceType())
7559 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
7561 return note(0, FD->getType(), FD->getBeginLoc());
7567 Info, Ctx, CheckingDest))
7573static bool checkBitCastConstexprEligibility(EvalInfo *Info,
7576 bool DestOK = checkBitCastConstexprEligibilityType(
7578 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
7584static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7587 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7588 "no host or target supports non 8-bit chars");
7590 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
7594 std::optional<BitCastBuffer> Buffer =
7595 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
7600 std::optional<APValue> MaybeDestValue =
7601 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
7602 if (!MaybeDestValue)
7605 DestValue = std::move(*MaybeDestValue);
7609static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7612 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7613 "no host or target supports non 8-bit chars");
7615 "LValueToRValueBitcast requires an lvalue operand!");
7617 LValue SourceLValue;
7619 SourceLValue.setFrom(Info.Ctx, SourceValue);
7622 SourceRValue,
true))
7625 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
7628template <
class Derived>
7629class ExprEvaluatorBase
7632 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
7634 return getDerived().Success(
V, E);
7636 bool DerivedZeroInitialization(
const Expr *E) {
7637 return getDerived().ZeroInitialization(E);
7643 template<
typename ConditionalOperator>
7645 assert(Info.checkingPotentialConstantExpression());
7650 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7657 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7664 Error(E, diag::note_constexpr_conditional_never_const);
7668 template<
typename ConditionalOperator>
7672 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
7673 CheckPotentialConstantConditional(E);
7676 if (Info.noteFailure()) {
7684 return StmtVisitorTy::Visit(EvalExpr);
7690 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
7693 return Info.CCEDiag(E, D);
7696 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
7698 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
7700 return BuiltinOp != 0 &&
7701 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
7705 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
7707 EvalInfo &getEvalInfo() {
return Info; }
7716 return Error(E, diag::note_invalid_subexpr_in_const_expr);
7719 bool VisitStmt(
const Stmt *) {
7720 llvm_unreachable(
"Expression evaluator should not be called on stmts");
7722 bool VisitExpr(
const Expr *E) {
7733 return StmtVisitorTy::Visit(E->
getSubExpr());
7737 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
7739 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
7741 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
7749 TempVersionRAII RAII(*Info.CurrentCall);
7750 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
7751 return StmtVisitorTy::Visit(E->
getExpr());
7754 TempVersionRAII RAII(*Info.CurrentCall);
7758 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
7759 return StmtVisitorTy::Visit(E->
getExpr());
7763 FullExpressionRAII
Scope(Info);
7770 return StmtVisitorTy::Visit(E->
getSubExpr());
7774 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
7775 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
7778 if (!Info.Ctx.getLangOpts().CPlusPlus20)
7779 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
7780 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
7783 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
7792 VisitIgnoredValue(E->
getLHS());
7793 return StmtVisitorTy::Visit(E->
getRHS());
7803 return DerivedSuccess(Result, E);
7816 if (!
Evaluate(Info.CurrentCall->createTemporary(
7819 ScopeKind::FullExpression, CommonLV),
7823 return HandleConditionalOperator(E);
7827 bool IsBcpCall =
false;
7834 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
7841 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
7844 FoldConstant Fold(Info, IsBcpCall);
7845 if (!HandleConditionalOperator(E)) {
7846 Fold.keepDiagnostics();
7854 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
7856 return DerivedSuccess(*
Value, E);
7862 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
7865 return StmtVisitorTy::Visit(Source);
7870 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
7879 if (OVE->isUnique())
7883 if (!
Evaluate(Info.CurrentCall->createTemporary(
7884 OVE, getStorageType(Info.Ctx, OVE),
7885 ScopeKind::FullExpression, LV),
7886 Info, OVE->getSourceExpr()))
7889 if (!StmtVisitorTy::Visit(SemE))
7899 bool VisitCallExpr(
const CallExpr *E) {
7901 if (!handleCallExpr(E, Result,
nullptr))
7903 return DerivedSuccess(Result, E);
7907 const LValue *ResultSlot) {
7908 CallScopeRAII CallScope(Info);
7914 LValue *
This =
nullptr, ThisVal;
7916 bool HasQualifier =
false;
7923 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
7927 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
7929 return Error(Callee);
7931 HasQualifier = ME->hasQualifier();
7932 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
7938 Member = dyn_cast<CXXMethodDecl>(D);
7940 return Error(Callee);
7942 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
7943 if (!Info.getLangOpts().CPlusPlus20)
7944 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
7948 return Error(Callee);
7955 if (!CalleeLV.getLValueOffset().isZero())
7956 return Error(Callee);
7957 if (CalleeLV.isNullPointer()) {
7958 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
7962 FD = dyn_cast_or_null<FunctionDecl>(
7963 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
7965 return Error(Callee);
7968 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
7975 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
7976 if (OCE && OCE->isAssignmentOp()) {
7977 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
7978 Call = Info.CurrentCall->createCall(FD);
7979 bool HasThis =
false;
7980 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
7981 HasThis = MD->isImplicitObjectMemberFunction();
8009 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8010 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8014 Args = Args.slice(1);
8023 "Number of captures must be zero for conversion to function-ptr");
8034 "A generic lambda's static-invoker function must be a "
8035 "template specialization");
8039 void *InsertPos =
nullptr;
8042 assert(CorrespondingCallOpSpecialization &&
8043 "We must always have a function call operator specialization "
8044 "that corresponds to our static invoker specialization");
8045 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8046 FD = CorrespondingCallOpSpecialization;
8055 Ptr.moveInto(Result);
8056 return CallScope.destroy();
8066 Call = Info.CurrentCall->createCall(FD);
8073 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8074 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8077 CovariantAdjustmentPath);
8080 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8090 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8091 assert(This &&
"no 'this' pointer for destructor call");
8093 Info.Ctx.getRecordType(DD->getParent())) &&
8094 CallScope.destroy();
8102 Body, Info, Result, ResultSlot))
8105 if (!CovariantAdjustmentPath.empty() &&
8107 CovariantAdjustmentPath))
8110 return CallScope.destroy();
8118 return DerivedZeroInitialization(E);
8120 return StmtVisitorTy::Visit(E->
getInit(0));
8124 return DerivedZeroInitialization(E);
8127 return DerivedZeroInitialization(E);
8130 return DerivedZeroInitialization(E);
8135 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8136 "missing temporary materialization conversion");
8137 assert(!E->
isArrow() &&
"missing call to bound member function?");
8146 if (!FD)
return Error(E);
8160 DerivedSuccess(Result, E);
8171 if (Indices.size() == 1) {
8173 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8177 for (
unsigned I = 0; I < Indices.size(); ++I) {
8180 APValue VecResult(Elts.data(), Indices.size());
8181 return DerivedSuccess(VecResult, E);
8188 bool VisitCastExpr(
const CastExpr *E) {
8193 case CK_AtomicToNonAtomic: {
8200 return DerivedSuccess(AtomicVal, E);
8204 case CK_UserDefinedConversion:
8205 return StmtVisitorTy::Visit(E->
getSubExpr());
8207 case CK_LValueToRValue: {
8216 return DerivedSuccess(RVal, E);
8218 case CK_LValueToRValueBitCast: {
8219 APValue DestValue, SourceValue;
8222 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
8224 return DerivedSuccess(DestValue, E);
8227 case CK_AddressSpaceConversion: {
8231 return DerivedSuccess(
Value, E);
8239 return VisitUnaryPostIncDec(UO);
8242 return VisitUnaryPostIncDec(UO);
8245 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8255 return DerivedSuccess(RVal, UO);
8258 bool VisitStmtExpr(
const StmtExpr *E) {
8268 BlockScopeRAII
Scope(Info);
8273 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8275 Info.FFDiag((*BI)->getBeginLoc(),
8276 diag::note_constexpr_stmt_expr_unsupported);
8279 return this->Visit(FinalExpr) &&
Scope.destroy();
8285 if (ESR != ESR_Succeeded) {
8289 if (ESR != ESR_Failed)
8290 Info.FFDiag((*BI)->getBeginLoc(),
8291 diag::note_constexpr_stmt_expr_unsupported);
8296 llvm_unreachable(
"Return from function from the loop above.");
8304 void VisitIgnoredValue(
const Expr *E) {
8309 void VisitIgnoredBaseExpression(
const Expr *E) {
8312 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
8314 VisitIgnoredValue(E);
8324template<
class Derived>
8325class LValueExprEvaluatorBase
8326 :
public ExprEvaluatorBase<Derived> {
8330 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8331 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8338 bool evaluatePointer(
const Expr *E, LValue &Result) {
8343 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8344 : ExprEvaluatorBaseTy(Info), Result(Result),
8345 InvalidBaseOK(InvalidBaseOK) {}
8348 Result.setFrom(this->Info.Ctx,
V);
8357 EvalOK = evaluatePointer(E->
getBase(), Result);
8364 EvalOK = this->Visit(E->
getBase());
8370 Result.setInvalid(E);
8385 return this->
Error(E);
8400 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8408 bool VisitCastExpr(
const CastExpr *E) {
8411 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8413 case CK_DerivedToBase:
8414 case CK_UncheckedDerivedToBase:
8461class LValueExprEvaluator
8462 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8464 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8465 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8467 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
8470 bool VisitCallExpr(
const CallExpr *E);
8485 return VisitUnaryPreIncDec(UO);
8488 return VisitUnaryPreIncDec(UO);
8493 bool VisitCastExpr(
const CastExpr *E) {
8496 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
8498 case CK_LValueBitCast:
8499 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
8500 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
8503 Result.Designator.setInvalid();
8506 case CK_BaseToDerived:
8523 bool LValueToRValueConversion) {
8527 assert(Info.CurrentCall->This ==
nullptr &&
8528 "This should not be set for a static call operator");
8536 if (Self->getType()->isReferenceType()) {
8537 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8538 Result.setFrom(Info.Ctx, *RefValue);
8540 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8541 CallStackFrame *Frame =
8542 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8544 unsigned Version = Info.CurrentCall->Arguments.Version;
8545 Result.set({VD, Frame->Index, Version});
8548 Result = *Info.CurrentCall->This;
8558 if (LValueToRValueConversion) {
8562 Result.setFrom(Info.Ctx, RVal);
8573 bool InvalidBaseOK) {
8577 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
8580bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
8584 return Success(cast<ValueDecl>(D));
8585 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
8586 return VisitVarDecl(E, VD);
8587 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
8588 return Visit(BD->getBinding());
8593bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
8600 isa<DeclRefExpr>(E) &&
8601 cast<DeclRefExpr>(E)->refersToEnclosingVariableOrCapture()) {
8606 if (Info.checkingPotentialConstantExpression())
8609 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8610 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8616 CallStackFrame *Frame =
nullptr;
8617 unsigned Version = 0;
8625 CallStackFrame *CurrFrame = Info.CurrentCall;
8626 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
8630 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
8631 if (CurrFrame->Arguments) {
8632 VD = CurrFrame->Arguments.getOrigParam(PVD);
8634 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
8635 Version = CurrFrame->Arguments.Version;
8639 Version = CurrFrame->getCurrentTemporaryVersion(VD);
8646 Result.set({VD, Frame->Index, Version});
8652 if (!Info.getLangOpts().CPlusPlus11) {
8653 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
8655 Info.Note(VD->
getLocation(), diag::note_declared_at);
8661 if (!
V->hasValue()) {
8664 if (!Info.checkingPotentialConstantExpression())
8665 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
8671bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
8672 if (!IsConstantEvaluatedBuiltinCall(E))
8673 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8678 case Builtin::BIas_const:
8679 case Builtin::BIforward:
8680 case Builtin::BIforward_like:
8681 case Builtin::BImove:
8682 case Builtin::BImove_if_noexcept:
8684 return Visit(E->
getArg(0));
8688 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8691bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
8700 for (
const Expr *E : CommaLHSs)
8709 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
8716 Value = &Info.CurrentCall->createTemporary(
8717 E, Inner->getType(),
8732 for (
unsigned I = Adjustments.size(); I != 0; ) {
8734 switch (Adjustments[I].Kind) {
8739 Type = Adjustments[I].DerivedToBase.BasePath->getType();
8745 Type = Adjustments[I].Field->getType();
8750 Adjustments[I].Ptr.RHS))
8752 Type = Adjustments[I].Ptr.MPT->getPointeeType();
8762 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
8763 "lvalue compound literal in c++?");
8769bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
8778 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
8779 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
8787 std::optional<DynamicType> DynType =
8793 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
8799bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
8803bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
8806 VisitIgnoredBaseExpression(E->
getBase());
8807 return VisitVarDecl(E, VD);
8812 if (MD->isStatic()) {
8813 VisitIgnoredBaseExpression(E->
getBase());
8819 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
8834 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr, Result)
8836 if (!Info.noteFailure())
8846bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
8847 return evaluatePointer(E->
getSubExpr(), Result);
8850bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
8859bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
8861 "lvalue __imag__ on scalar?");
8868bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
8869 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8880bool LValueExprEvaluator::VisitCompoundAssignOperator(
8882 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8890 if (!Info.noteFailure())
8905bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
8906 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8914 if (!Info.noteFailure())
8922 if (Info.getLangOpts().CPlusPlus20 &&
8942 llvm::APInt &Result) {
8943 const AllocSizeAttr *AllocSize = getAllocSizeAttr(
Call);
8945 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
8946 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
8948 if (
Call->getNumArgs() <= SizeArgNo)
8951 auto EvaluateAsSizeT = [&](
const Expr *E,
APSInt &Into) {
8956 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
8958 Into = Into.zext(BitsInSizeT);
8963 if (!EvaluateAsSizeT(
Call->getArg(SizeArgNo), SizeOfElem))
8966 if (!AllocSize->getNumElemsParam().isValid()) {
8967 Result = std::move(SizeOfElem);
8972 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
8973 if (!EvaluateAsSizeT(
Call->getArg(NumArgNo), NumberOfElems))
8977 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
8981 Result = std::move(BytesAvailable);
8989 llvm::APInt &Result) {
8990 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
8991 "Can't get the size of a non alloc_size function");
8992 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9012 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9017 if (!
Init ||
Init->getType().isNull())
9020 const Expr *E =
Init->IgnoreParens();
9021 if (!tryUnwrapAllocSizeCall(E))
9026 Result.setInvalid(E);
9029 Result.addUnsizedArray(Info, E, Pointee);
9034class PointerExprEvaluator
9035 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9044 bool evaluateLValue(
const Expr *E, LValue &Result) {
9048 bool evaluatePointer(
const Expr *E, LValue &Result) {
9052 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9055 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9056 : ExprEvaluatorBaseTy(info), Result(Result),
9057 InvalidBaseOK(InvalidBaseOK) {}
9060 Result.setFrom(Info.Ctx,
V);
9063 bool ZeroInitialization(
const Expr *E) {
9064 Result.setNull(Info.Ctx, E->
getType());
9069 bool VisitCastExpr(
const CastExpr* E);
9076 if (Info.noteFailure())
9082 bool VisitCallExpr(
const CallExpr *E);
9083 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9084 bool VisitBlockExpr(
const BlockExpr *E) {
9090 auto DiagnoseInvalidUseOfThis = [&] {
9091 if (Info.getLangOpts().CPlusPlus11)
9092 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9098 if (Info.checkingPotentialConstantExpression())
9101 bool IsExplicitLambda =
9103 if (!IsExplicitLambda) {
9104 if (!Info.CurrentCall->This) {
9105 DiagnoseInvalidUseOfThis();
9109 Result = *Info.CurrentCall->This;
9117 if (!Info.CurrentCall->LambdaThisCaptureField) {
9118 if (IsExplicitLambda && !Info.CurrentCall->This) {
9119 DiagnoseInvalidUseOfThis();
9126 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9128 Info, E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9129 Info.CurrentCall->LambdaThisCaptureField->getType()->isPointerType());
9137 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9139 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9140 Result.setFrom(Info.Ctx, LValResult);
9148 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9149 ResultStr.size() + 1);
9150 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9151 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9157 evaluateLValue(SL, Result);
9158 Result.addArray(Info, E, cast<ConstantArrayType>(ArrayTy));
9167 bool InvalidBaseOK) {
9170 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9173bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9176 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9181 std::swap(PExp, IExp);
9183 bool EvalPtrOK = evaluatePointer(PExp, Result);
9184 if (!EvalPtrOK && !Info.noteFailure())
9187 llvm::APSInt Offset;
9198bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
9199 return evaluateLValue(E->
getSubExpr(), Result);
9207 if (!FnII || !FnII->
isStr(
"current"))
9210 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9218bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9225 case CK_CPointerToObjCPointerCast:
9226 case CK_BlockPointerToObjCPointerCast:
9227 case CK_AnyPointerToBlockPointerCast:
9228 case CK_AddressSpaceConversion:
9229 if (!Visit(SubExpr))
9237 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9239 bool VoidPtrCastMaybeOK =
9241 Info.Ctx.hasSameUnqualifiedType(Result.Designator.getType(Info.Ctx),
9250 if (VoidPtrCastMaybeOK &&
9251 (Info.getStdAllocatorCaller(
"allocate") ||
9253 Info.getLangOpts().CPlusPlus26)) {
9257 Info.getLangOpts().CPlusPlus) {
9259 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
9260 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9261 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9264 CCEDiag(E, diag::note_constexpr_invalid_cast)
9267 CCEDiag(E, diag::note_constexpr_invalid_cast)
9268 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9269 Result.Designator.setInvalid();
9272 if (E->
getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9273 ZeroInitialization(E);
9276 case CK_DerivedToBase:
9277 case CK_UncheckedDerivedToBase:
9278 if (!evaluatePointer(E->
getSubExpr(), Result))
9280 if (!Result.Base && Result.Offset.isZero())
9289 case CK_BaseToDerived:
9292 if (!Result.Base && Result.Offset.isZero())
9301 case CK_NullToPointer:
9303 return ZeroInitialization(E);
9305 case CK_IntegralToPointer: {
9306 CCEDiag(E, diag::note_constexpr_invalid_cast)
9307 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9313 if (
Value.isInt()) {
9314 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
9315 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9316 Result.Base = (
Expr*)
nullptr;
9317 Result.InvalidBase =
false;
9319 Result.Designator.setInvalid();
9320 Result.IsNullPtr =
false;
9324 Result.setFrom(Info.Ctx,
Value);
9329 case CK_ArrayToPointerDecay: {
9331 if (!evaluateLValue(SubExpr, Result))
9335 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9340 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9341 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9342 Result.addArray(Info, E, CAT);
9344 Result.addUnsizedArray(Info, E, AT->getElementType());
9348 case CK_FunctionToPointerDecay:
9349 return evaluateLValue(SubExpr, Result);
9351 case CK_LValueToRValue: {
9360 return InvalidBaseOK &&
9366 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9374 T =
T.getNonReferenceType();
9376 if (
T.getQualifiers().hasUnaligned())
9379 const bool AlignOfReturnsPreferred =
9380 Info.Ctx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9385 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9386 return Info.Ctx.toCharUnitsFromBits(
9387 Info.Ctx.getPreferredTypeAlign(
T.getTypePtr()));
9389 else if (ExprKind == UETT_AlignOf)
9390 return Info.Ctx.getTypeAlignInChars(
T.getTypePtr());
9392 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9405 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
9406 return Info.Ctx.getDeclAlign(DRE->getDecl(),
9409 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
9410 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
9418 return Info.Ctx.getDeclAlign(VD);
9419 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
9427 EvalInfo &Info,
APSInt &Alignment) {
9430 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9431 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
9434 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9435 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9436 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9437 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
9438 << MaxValue << ForType << Alignment;
9444 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9445 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9446 "Alignment should not be changed by ext/trunc");
9447 Alignment = ExtAlignment;
9448 assert(Alignment.getBitWidth() == SrcWidth);
9453bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
9454 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
9457 if (!(InvalidBaseOK && getAllocSizeAttr(E)))
9460 Result.setInvalid(E);
9462 Result.addUnsizedArray(Info, E, PointeeTy);
9466bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9467 if (!IsConstantEvaluatedBuiltinCall(E))
9468 return visitNonBuiltinCallExpr(E);
9478bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
9479 unsigned BuiltinOp) {
9483 switch (BuiltinOp) {
9484 case Builtin::BIaddressof:
9485 case Builtin::BI__addressof:
9486 case Builtin::BI__builtin_addressof:
9487 return evaluateLValue(E->
getArg(0), Result);
9488 case Builtin::BI__builtin_assume_aligned: {
9492 if (!evaluatePointer(E->
getArg(0), Result))
9495 LValue OffsetResult(Result);
9507 int64_t AdditionalOffset = -Offset.getZExtValue();
9512 if (OffsetResult.Base) {
9515 if (BaseAlignment < Align) {
9516 Result.Designator.setInvalid();
9519 diag::note_constexpr_baa_insufficient_alignment) << 0
9527 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
9528 Result.Designator.setInvalid();
9532 diag::note_constexpr_baa_insufficient_alignment) << 1
9534 diag::note_constexpr_baa_value_insufficient_alignment))
9535 << (
int)OffsetResult.Offset.getQuantity()
9542 case Builtin::BI__builtin_align_up:
9543 case Builtin::BI__builtin_align_down: {
9544 if (!evaluatePointer(E->
getArg(0), Result))
9563 assert(Alignment.getBitWidth() <= 64 &&
9564 "Cannot handle > 64-bit address-space");
9565 uint64_t Alignment64 = Alignment.getZExtValue();
9567 BuiltinOp == Builtin::BI__builtin_align_down
9568 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
9569 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
9570 Result.adjustOffset(NewOffset - Result.Offset);
9575 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
9579 case Builtin::BI__builtin_operator_new:
9581 case Builtin::BI__builtin_launder:
9582 return evaluatePointer(E->
getArg(0), Result);
9583 case Builtin::BIstrchr:
9584 case Builtin::BIwcschr:
9585 case Builtin::BImemchr:
9586 case Builtin::BIwmemchr:
9587 if (Info.getLangOpts().CPlusPlus11)
9588 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9590 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9592 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
9594 case Builtin::BI__builtin_strchr:
9595 case Builtin::BI__builtin_wcschr:
9596 case Builtin::BI__builtin_memchr:
9597 case Builtin::BI__builtin_char_memchr:
9598 case Builtin::BI__builtin_wmemchr: {
9599 if (!Visit(E->
getArg(0)))
9605 if (BuiltinOp != Builtin::BIstrchr &&
9606 BuiltinOp != Builtin::BIwcschr &&
9607 BuiltinOp != Builtin::BI__builtin_strchr &&
9608 BuiltinOp != Builtin::BI__builtin_wcschr) {
9612 MaxLength = N.getZExtValue();
9615 if (MaxLength == 0u)
9616 return ZeroInitialization(E);
9617 if (!Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
9618 Result.Designator.Invalid)
9620 QualType CharTy = Result.Designator.getType(Info.Ctx);
9621 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
9622 BuiltinOp == Builtin::BI__builtin_memchr;
9624 Info.Ctx.hasSameUnqualifiedType(
9628 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
9634 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
9635 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
9642 bool StopAtNull =
false;
9643 switch (BuiltinOp) {
9644 case Builtin::BIstrchr:
9645 case Builtin::BI__builtin_strchr:
9652 return ZeroInitialization(E);
9655 case Builtin::BImemchr:
9656 case Builtin::BI__builtin_memchr:
9657 case Builtin::BI__builtin_char_memchr:
9661 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
9664 case Builtin::BIwcschr:
9665 case Builtin::BI__builtin_wcschr:
9668 case Builtin::BIwmemchr:
9669 case Builtin::BI__builtin_wmemchr:
9671 DesiredVal = Desired.getZExtValue();
9675 for (; MaxLength; --MaxLength) {
9680 if (Char.
getInt().getZExtValue() == DesiredVal)
9682 if (StopAtNull && !Char.
getInt())
9688 return ZeroInitialization(E);
9691 case Builtin::BImemcpy:
9692 case Builtin::BImemmove:
9693 case Builtin::BIwmemcpy:
9694 case Builtin::BIwmemmove:
9695 if (Info.getLangOpts().CPlusPlus11)
9696 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9698 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9700 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
9702 case Builtin::BI__builtin_memcpy:
9703 case Builtin::BI__builtin_memmove:
9704 case Builtin::BI__builtin_wmemcpy:
9705 case Builtin::BI__builtin_wmemmove: {
9706 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
9707 BuiltinOp == Builtin::BIwmemmove ||
9708 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
9709 BuiltinOp == Builtin::BI__builtin_wmemmove;
9710 bool Move = BuiltinOp == Builtin::BImemmove ||
9711 BuiltinOp == Builtin::BIwmemmove ||
9712 BuiltinOp == Builtin::BI__builtin_memmove ||
9713 BuiltinOp == Builtin::BI__builtin_wmemmove;
9716 if (!Visit(E->
getArg(0)))
9718 LValue Dest = Result;
9727 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
9737 if (!Src.Base || !Dest.Base) {
9739 (!Src.Base ? Src : Dest).moveInto(Val);
9740 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
9741 <<
Move << WChar << !!Src.Base
9745 if (Src.Designator.Invalid || Dest.Designator.Invalid)
9751 QualType T = Dest.Designator.getType(Info.Ctx);
9752 QualType SrcT = Src.Designator.getType(Info.Ctx);
9753 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
9755 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
9759 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
9762 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
9763 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
9768 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
9773 llvm::APInt OrigN = N;
9774 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
9776 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
9786 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
9787 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
9788 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
9789 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
9790 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
9794 uint64_t NElems = N.getZExtValue();
9800 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
9801 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
9802 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
9805 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
9813 }
else if (!Move && SrcOffset >= DestOffset &&
9814 SrcOffset - DestOffset < NBytes) {
9816 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
9851bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
9852 if (!Info.getLangOpts().CPlusPlus20)
9853 Info.CCEDiag(E, diag::note_constexpr_new);
9856 if (Info.SpeculativeEvaluationDepth)
9861 bool IsNothrow =
false;
9862 bool IsPlacement =
false;
9864 Info.CurrentCall->isStdFunction() && !E->
isArray()) {
9869 if (Result.Designator.Invalid)
9873 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
9874 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
9889 return Error(E, diag::note_constexpr_new_placement);
9900 bool ValueInit =
false;
9903 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
9904 const Expr *Stripped = *ArraySize;
9905 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
9906 Stripped = ICE->getSubExpr())
9907 if (ICE->getCastKind() != CK_NoOp &&
9908 ICE->getCastKind() != CK_IntegralCast)
9911 llvm::APSInt ArrayBound;
9919 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
9921 return ZeroInitialization(E);
9923 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
9924 << ArrayBound << (*ArraySize)->getSourceRange();
9930 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
9932 Info.Ctx, AllocType, ArrayBound),
9933 ArrayBound.getZExtValue(), !IsNothrow)) {
9935 return ZeroInitialization(E);
9944 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
9945 isa<ImplicitValueInitExpr>(
Init)) {
9947 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
9948 ResizedArrayCCE = CCE;
9950 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
9951 assert(CAT &&
"unexpected type for array initializer");
9955 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
9956 llvm::APInt AllocBound = ArrayBound.zext(Bits);
9957 if (InitBound.ugt(AllocBound)) {
9959 return ZeroInitialization(E);
9961 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
9964 << (*ArraySize)->getSourceRange();
9970 if (InitBound != AllocBound)
9971 ResizedArrayILE = cast<InitListExpr>(
Init);
9974 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
9975 ArraySizeModifier::Normal, 0);
9978 "array allocation with non-array new");
9984 struct FindObjectHandler {
9991 typedef bool result_type;
9992 bool failed() {
return false; }
9996 if (!Info.Ctx.hasSameUnqualifiedType(SubobjType, AllocType)) {
9997 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type) <<
9998 SubobjType << AllocType;
10005 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10009 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10012 } Handler = {Info, E, AllocType, AK,
nullptr};
10015 if (!Obj || !
findSubobject(Info, E, Obj, Result.Designator, Handler))
10018 Val = Handler.Value;
10027 Val = Info.createHeapAlloc(E, AllocType, Result);
10036 }
else if (ResizedArrayILE) {
10040 }
else if (ResizedArrayCCE) {
10054 Result.addArray(Info, E, cast<ConstantArrayType>(AT));
10063class MemberPointerExprEvaluator
10064 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10068 Result = MemberPtr(D);
10073 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10074 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10080 bool ZeroInitialization(
const Expr *E) {
10084 bool VisitCastExpr(
const CastExpr *E);
10093 return MemberPointerExprEvaluator(Info, Result).Visit(E);
10096bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10099 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10101 case CK_NullToMemberPointer:
10103 return ZeroInitialization(E);
10105 case CK_BaseToDerivedMemberPointer: {
10113 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10115 PathI != PathE; ++PathI) {
10116 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10117 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10118 if (!Result.castToDerived(Derived))
10127 case CK_DerivedToBaseMemberPointer:
10131 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10132 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10134 if (!Result.castToBase(
Base))
10141bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10152 class RecordExprEvaluator
10153 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10154 const LValue &
This;
10158 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10159 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10165 bool ZeroInitialization(
const Expr *E) {
10166 return ZeroInitialization(E, E->
getType());
10170 bool VisitCallExpr(
const CallExpr *E) {
10171 return handleCallExpr(E, Result, &This);
10173 bool VisitCastExpr(
const CastExpr *E);
10176 return VisitCXXConstructExpr(E, E->
getType());
10184 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10198 const LValue &This,
APValue &Result) {
10199 assert(!RD->
isUnion() &&
"Expected non-union class type");
10208 unsigned Index = 0;
10210 End = CD->
bases_end(); I != End; ++I, ++Index) {
10212 LValue Subobject = This;
10216 Result.getStructBase(Index)))
10221 for (
const auto *I : RD->
fields()) {
10223 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10226 LValue Subobject = This;
10232 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10239bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
10246 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10253 LValue Subobject =
This;
10258 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10261 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10262 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
10269bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10272 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10274 case CK_ConstructorConversion:
10277 case CK_DerivedToBase:
10278 case CK_UncheckedDerivedToBase: {
10289 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10290 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10301bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10304 return VisitCXXParenListOrInitListExpr(E, E->
inits());
10307bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10313 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10315 EvalInfo::EvaluatingConstructorRAII EvalObj(
10317 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10318 CXXRD && CXXRD->getNumBases());
10322 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10323 Field = ILE->getInitializedFieldInUnion();
10324 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10325 Field = PLIE->getInitializedFieldInUnion();
10328 "Expression is neither an init list nor a C++ paren list");
10341 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10343 LValue Subobject =
This;
10348 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10349 isa<CXXDefaultInitExpr>(InitExpr));
10351 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10352 if (
Field->isBitField())
10361 if (!Result.hasValue())
10364 unsigned ElementNo = 0;
10368 if (CXXRD && CXXRD->getNumBases()) {
10369 for (
const auto &
Base : CXXRD->bases()) {
10370 assert(ElementNo < Args.size() &&
"missing init for base class");
10371 const Expr *
Init = Args[ElementNo];
10373 LValue Subobject =
This;
10377 APValue &FieldVal = Result.getStructBase(ElementNo);
10379 if (!Info.noteFailure())
10386 EvalObj.finishedConstructingBases();
10390 for (
const auto *Field : RD->
fields()) {
10393 if (
Field->isUnnamedBitField())
10396 LValue Subobject =
This;
10398 bool HaveInit = ElementNo < Args.size();
10403 Subobject, Field, &Layout))
10409 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10411 if (
Field->getType()->isIncompleteArrayType()) {
10412 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10416 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10423 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10424 isa<CXXDefaultInitExpr>(
Init));
10426 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10429 FieldVal, Field))) {
10430 if (!Info.noteFailure())
10436 EvalObj.finishedConstructingFields();
10451 if (Result.hasValue())
10455 return ZeroInitialization(E,
T);
10475 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
10477 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10478 return Visit(ME->getSubExpr());
10481 if (ZeroInit && !ZeroInitialization(E,
T))
10490bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10492 if (!Info.CurrentCall) {
10493 assert(Info.checkingPotentialConstantExpression());
10512bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10521 assert(
ArrayType &&
"unexpected type for array initializer");
10526 auto InvalidType = [&] {
10527 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
10535 if (Field ==
Record->field_end())
10536 return InvalidType();
10539 if (!
Field->getType()->isPointerType() ||
10540 !Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10542 return InvalidType();
10546 Array.moveInto(Result.getStructField(0));
10548 if (++Field ==
Record->field_end())
10549 return InvalidType();
10551 if (
Field->getType()->isPointerType() &&
10552 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10559 Array.moveInto(Result.getStructField(1));
10560 }
else if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType()))
10564 return InvalidType();
10566 if (++Field !=
Record->field_end())
10567 return InvalidType();
10572bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
10577 const size_t NumFields =
10582 "The number of lambda capture initializers should equal the number of "
10583 "fields within the closure type");
10590 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10591 for (
const auto *Field : ClosureClass->
fields()) {
10594 Expr *
const CurFieldInit = *CaptureInitIt++;
10601 LValue Subobject =
This;
10606 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10608 if (!Info.keepEvaluatingAfterFailure())
10617 APValue &Result, EvalInfo &Info) {
10620 "can't evaluate expression as a record rvalue");
10621 return RecordExprEvaluator(Info, This, Result).Visit(E);
10632class TemporaryExprEvaluator
10633 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
10635 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
10636 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
10639 bool VisitConstructExpr(
const Expr *E) {
10641 E, E->
getType(), ScopeKind::FullExpression, Result);
10645 bool VisitCastExpr(
const CastExpr *E) {
10648 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
10650 case CK_ConstructorConversion:
10655 return VisitConstructExpr(E);
10658 return VisitConstructExpr(E);
10660 bool VisitCallExpr(
const CallExpr *E) {
10661 return VisitConstructExpr(E);
10664 return VisitConstructExpr(E);
10667 return VisitConstructExpr(E);
10676 return TemporaryExprEvaluator(Info, Result).Visit(E);
10684 class VectorExprEvaluator
10685 :
public ExprEvaluatorBase<VectorExprEvaluator> {
10689 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
10690 : ExprEvaluatorBaseTy(info), Result(Result) {}
10699 assert(
V.isVector());
10703 bool ZeroInitialization(
const Expr *E);
10707 bool VisitCastExpr(
const CastExpr* E);
10719 "not a vector prvalue");
10720 return VectorExprEvaluator(Info, Result).Visit(E);
10723bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10731 case CK_VectorSplat: {
10737 Val =
APValue(std::move(IntResult));
10742 Val =
APValue(std::move(FloatResult));
10759 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
10760 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
10764 if (!handleRValueToRValueBitCast(Info, Result, SVal, E))
10770 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10775VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10787 unsigned CountInits = 0, CountElts = 0;
10788 while (CountElts < NumElements) {
10790 if (CountInits < NumInits
10795 unsigned vlen =
v.getVectorLength();
10796 for (
unsigned j = 0; j < vlen; j++)
10797 Elements.push_back(
v.getVectorElt(j));
10800 llvm::APSInt sInt(32);
10801 if (CountInits < NumInits) {
10805 sInt = Info.Ctx.MakeIntValue(0, EltTy);
10806 Elements.push_back(
APValue(sInt));
10809 llvm::APFloat f(0.0);
10810 if (CountInits < NumInits) {
10814 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
10815 Elements.push_back(
APValue(f));
10824VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
10828 if (EltTy->isIntegerType())
10829 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
10832 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
10838bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
10840 return ZeroInitialization(E);
10843bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10845 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
10846 "Operation not supported on vector types");
10848 if (Op == BO_Comma)
10849 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10855 "Must both be vector types");
10862 "All operands must be the same size.");
10866 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
10867 if (!LHSOK && !Info.noteFailure())
10869 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
10891 "Vector can only be int or float type");
10899 "Vector operator ~ can only be int");
10900 Elt.
getInt().flipAllBits();
10910 "Vector can only be int or float type");
10916 EltResult.setAllBits();
10918 EltResult.clearAllBits();
10924 return std::nullopt;
10928bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
10934 const QualType ResultEltTy = VD->getElementType();
10938 if (!
Evaluate(SubExprValue, Info, SubExpr))
10951 "Vector length doesn't match type?");
10954 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
10956 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
10959 ResultElements.push_back(*Elt);
10961 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
10969 class ArrayExprEvaluator
10970 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
10971 const LValue &
This;
10975 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
10976 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
10979 assert(
V.isArray() &&
"expected array");
10984 bool ZeroInitialization(
const Expr *E) {
10986 Info.Ctx.getAsConstantArrayType(E->
getType());
11000 if (!Result.hasArrayFiller())
11004 LValue Subobject =
This;
11005 Subobject.addArray(Info, E, CAT);
11007 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11010 bool VisitCallExpr(
const CallExpr *E) {
11011 return handleCallExpr(E, Result, &This);
11018 const LValue &Subobject,
11026 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11028 const Expr *ArrayFiller,
11034 APValue &Result, EvalInfo &Info) {
11037 "not an array prvalue");
11038 return ArrayExprEvaluator(Info, This, Result).Visit(E);
11046 "not an array prvalue");
11047 return ArrayExprEvaluator(Info, This, Result)
11048 .VisitInitListExpr(ILE, AllocType);
11057 "not an array prvalue");
11058 return ArrayExprEvaluator(Info, This, Result)
11059 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11066 if (isa<ImplicitValueInitExpr>(FillerExpr))
11068 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11069 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
11074 if (ILE->hasArrayFiller() &&
11083bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
11098 return VisitStringLiteral(SL, AllocType);
11103 "transparent array list initialization is not string literal init?");
11109bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11117 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11118 "zero-initialized array shouldn't have any initialized elts");
11120 if (Result.isArray() && Result.hasArrayFiller())
11121 Filler = Result.getArrayFiller();
11123 unsigned NumEltsToInit = Args.size();
11129 NumEltsToInit = NumElts;
11131 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11132 << NumEltsToInit <<
".\n");
11139 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I)
11140 Result.getArrayInitializedElt(I) = Filler;
11141 if (Result.hasArrayFiller())
11142 Result.getArrayFiller() = Filler;
11145 LValue Subobject =
This;
11146 Subobject.addArray(Info, ExprToVisit, CAT);
11147 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11148 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11150 Info, Subobject,
Init) ||
11153 if (!Info.noteFailure())
11159 if (!Result.hasArrayFiller())
11164 assert(ArrayFiller &&
"no array filler for incomplete init list");
11173 !
Evaluate(Info.CurrentCall->createTemporary(
11176 ScopeKind::FullExpression, CommonLV),
11185 LValue Subobject =
This;
11186 Subobject.addArray(Info, E, CAT);
11189 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11198 FullExpressionRAII
Scope(Info);
11204 if (!Info.noteFailure())
11216bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11217 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
11221 const LValue &Subobject,
11231 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11235 if (FinalSize == 0)
11241 LValue ArrayElt = Subobject;
11242 ArrayElt.addArray(Info, E, CAT);
11248 for (
const unsigned N : {1u, FinalSize}) {
11249 unsigned OldElts =
Value->getArrayInitializedElts();
11255 for (
unsigned I = 0; I < OldElts; ++I)
11256 NewValue.getArrayInitializedElt(I).swap(
11257 Value->getArrayInitializedElt(I));
11258 Value->swap(NewValue);
11261 for (
unsigned I = OldElts; I < N; ++I)
11262 Value->getArrayInitializedElt(I) = Filler;
11264 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11267 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11268 for (
unsigned I = OldElts; I < FinalSize; ++I)
11269 Value->getArrayInitializedElt(I) = FirstResult;
11271 for (
unsigned I = OldElts; I < N; ++I) {
11272 if (!VisitCXXConstructExpr(E, ArrayElt,
11273 &
Value->getArrayInitializedElt(I),
11280 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11281 !Info.keepEvaluatingAfterFailure())
11293 return RecordExprEvaluator(Info, Subobject, *
Value)
11294 .VisitCXXConstructExpr(E,
Type);
11297bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11299 assert(dyn_cast<ConstantArrayType>(E->
getType()) &&
11300 "Expression result is not a constant array type");
11302 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
11315class IntExprEvaluator
11316 :
public ExprEvaluatorBase<IntExprEvaluator> {
11319 IntExprEvaluator(EvalInfo &info,
APValue &result)
11320 : ExprEvaluatorBaseTy(info), Result(result) {}
11324 "Invalid evaluation result.");
11326 "Invalid evaluation result.");
11327 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
11328 "Invalid evaluation result.");
11332 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
11333 return Success(SI, E, Result);
11338 "Invalid evaluation result.");
11339 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
11340 "Invalid evaluation result.");
11342 Result.getInt().setIsUnsigned(
11346 bool Success(
const llvm::APInt &I,
const Expr *E) {
11347 return Success(I, E, Result);
11352 "Invalid evaluation result.");
11365 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate()) {
11372 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
11385 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
11387 if (CheckReferencedDecl(E, E->
getDecl()))
11390 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
11394 VisitIgnoredBaseExpression(E->
getBase());
11398 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
11401 bool VisitCallExpr(
const CallExpr *E);
11402 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
11407 bool VisitCastExpr(
const CastExpr* E);
11419 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
11425 return Success(Info.ArrayInitIndex, E);
11430 return ZeroInitialization(E);
11456class FixedPointExprEvaluator
11457 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
11461 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
11462 : ExprEvaluatorBaseTy(info), Result(result) {}
11464 bool Success(
const llvm::APInt &I,
const Expr *E) {
11466 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
11471 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
11475 return Success(
V.getFixedPoint(), E);
11480 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
11481 "Invalid evaluation result.");
11486 bool ZeroInitialization(
const Expr *E) {
11498 bool VisitCastExpr(
const CastExpr *E);
11516 return IntExprEvaluator(Info, Result).Visit(E);
11524 if (!Val.
isInt()) {
11527 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
11534bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
11536 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
11545 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
11560 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
11564 Result = APFixedPoint(Val, FXSema);
11575bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
11579 bool SameSign = (ECD->getInitVal().isSigned()
11581 bool SameWidth = (ECD->getInitVal().getBitWidth()
11582 == Info.Ctx.getIntWidth(E->
getType()));
11583 if (SameSign && SameWidth)
11584 return Success(ECD->getInitVal(), E);
11588 llvm::APSInt Val = ECD->getInitVal();
11590 Val.setIsSigned(!ECD->getInitVal().isSigned());
11592 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
11608#define TYPE(ID, BASE)
11609#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
11610#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
11611#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
11612#include "clang/AST/TypeNodes.inc"
11614 case Type::DeducedTemplateSpecialization:
11615 llvm_unreachable(
"unexpected non-canonical or dependent type");
11617 case Type::Builtin:
11618 switch (cast<BuiltinType>(CanTy)->
getKind()) {
11619#define BUILTIN_TYPE(ID, SINGLETON_ID)
11620#define SIGNED_TYPE(ID, SINGLETON_ID) \
11621 case BuiltinType::ID: return GCCTypeClass::Integer;
11622#define FLOATING_TYPE(ID, SINGLETON_ID) \
11623 case BuiltinType::ID: return GCCTypeClass::RealFloat;
11624#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
11625 case BuiltinType::ID: break;
11626#include "clang/AST/BuiltinTypes.def"
11627 case BuiltinType::Void:
11628 return GCCTypeClass::Void;
11630 case BuiltinType::Bool:
11631 return GCCTypeClass::Bool;
11633 case BuiltinType::Char_U:
11634 case BuiltinType::UChar:
11635 case BuiltinType::WChar_U:
11636 case BuiltinType::Char8:
11637 case BuiltinType::Char16:
11638 case BuiltinType::Char32:
11639 case BuiltinType::UShort:
11640 case BuiltinType::UInt:
11641 case BuiltinType::ULong:
11642 case BuiltinType::ULongLong:
11643 case BuiltinType::UInt128:
11644 return GCCTypeClass::Integer;
11646 case BuiltinType::UShortAccum:
11647 case BuiltinType::UAccum:
11648 case BuiltinType::ULongAccum:
11649 case BuiltinType::UShortFract:
11650 case BuiltinType::UFract:
11651 case BuiltinType::ULongFract:
11652 case BuiltinType::SatUShortAccum:
11653 case BuiltinType::SatUAccum:
11654 case BuiltinType::SatULongAccum:
11655 case BuiltinType::SatUShortFract:
11656 case BuiltinType::SatUFract:
11657 case BuiltinType::SatULongFract:
11658 return GCCTypeClass::None;
11660 case BuiltinType::NullPtr:
11662 case BuiltinType::ObjCId:
11663 case BuiltinType::ObjCClass:
11664 case BuiltinType::ObjCSel:
11665#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
11666 case BuiltinType::Id:
11667#include "clang/Basic/OpenCLImageTypes.def"
11668#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
11669 case BuiltinType::Id:
11670#include "clang/Basic/OpenCLExtensionTypes.def"
11671 case BuiltinType::OCLSampler:
11672 case BuiltinType::OCLEvent:
11673 case BuiltinType::OCLClkEvent:
11674 case BuiltinType::OCLQueue:
11675 case BuiltinType::OCLReserveID:
11676#define SVE_TYPE(Name, Id, SingletonId) \
11677 case BuiltinType::Id:
11678#include "clang/Basic/AArch64SVEACLETypes.def"
11679#define PPC_VECTOR_TYPE(Name, Id, Size) \
11680 case BuiltinType::Id:
11681#include "clang/Basic/PPCTypes.def"
11682#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11683#include "clang/Basic/RISCVVTypes.def"
11684#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11685#include "clang/Basic/WebAssemblyReferenceTypes.def"
11686 return GCCTypeClass::None;
11688 case BuiltinType::Dependent:
11689 llvm_unreachable(
"unexpected dependent type");
11691 llvm_unreachable(
"unexpected placeholder type");
11694 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
11696 case Type::Pointer:
11697 case Type::ConstantArray:
11698 case Type::VariableArray:
11699 case Type::IncompleteArray:
11700 case Type::FunctionNoProto:
11701 case Type::FunctionProto:
11702 case Type::ArrayParameter:
11703 return GCCTypeClass::Pointer;
11705 case Type::MemberPointer:
11707 ? GCCTypeClass::PointerToDataMember
11708 : GCCTypeClass::PointerToMemberFunction;
11710 case Type::Complex:
11711 return GCCTypeClass::Complex;
11714 return CanTy->
isUnionType() ? GCCTypeClass::Union
11715 : GCCTypeClass::ClassOrStruct;
11723 case Type::ExtVector:
11724 return GCCTypeClass::Vector;
11726 case Type::BlockPointer:
11727 case Type::ConstantMatrix:
11728 case Type::ObjCObject:
11729 case Type::ObjCInterface:
11730 case Type::ObjCObjectPointer:
11734 return GCCTypeClass::None;
11737 return GCCTypeClass::BitInt;
11739 case Type::LValueReference:
11740 case Type::RValueReference:
11741 llvm_unreachable(
"invalid type for expression");
11744 llvm_unreachable(
"unexpected type class");
11754 return GCCTypeClass::None;
11769 if (
Base.isNull()) {
11772 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
11773 if (!isa<StringLiteral>(E))
11791 SpeculativeEvaluationRAII SpeculativeEval(Info);
11796 FoldConstant Fold(Info,
true);
11819 Fold.keepDiagnostics();
11828 return V.hasValue();
11839 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
11842 if (isa<CompoundLiteralExpr>(E))
11863 const auto *Cast = dyn_cast<CastExpr>(NoParens);
11864 if (Cast ==
nullptr)
11869 auto CastKind = Cast->getCastKind();
11871 CastKind != CK_AddressSpaceConversion)
11874 const auto *SubExpr = Cast->getSubExpr();
11896 assert(!LVal.Designator.Invalid);
11898 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
11907 auto &
Base = LVal.getLValueBase();
11908 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
11909 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
11911 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
11913 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
11914 for (
auto *FD : IFD->chain()) {
11916 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
11924 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
11934 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
11935 const auto &Entry = LVal.Designator.Entries[I];
11941 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
11942 uint64_t Index = Entry.getAsArrayIndex();
11948 uint64_t Index = Entry.getAsArrayIndex();
11951 BaseType = CT->getElementType();
11952 }
else if (
auto *FD = getAsField(Entry)) {
11954 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
11958 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
11970 if (LVal.Designator.Invalid)
11973 if (!LVal.Designator.Entries.empty())
11974 return LVal.Designator.isMostDerivedAnUnsizedArray();
11976 if (!LVal.InvalidBase)
11981 const auto *E = LVal.Base.dyn_cast<
const Expr *>();
11982 return !E || !isa<MemberExpr>(E);
11988 const SubobjectDesignator &
Designator = LVal.Designator;
12000 auto isFlexibleArrayMember = [&] {
12002 FAMKind StrictFlexArraysLevel =
12005 if (
Designator.isMostDerivedAnUnsizedArray())
12008 if (StrictFlexArraysLevel == FAMKind::Default)
12011 if (
Designator.getMostDerivedArraySize() == 0 &&
12012 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12015 if (
Designator.getMostDerivedArraySize() == 1 &&
12016 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12022 return LVal.InvalidBase &&
12024 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12032 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12033 if (Int.ugt(CharUnitsMax))
12045 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12046 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12058 unsigned Type,
const LValue &LVal,
12071 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12073 if (
Type == 3 && !DetermineForCompleteObject)
12076 llvm::APInt APEndOffset;
12077 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12081 if (LVal.InvalidBase)
12085 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12091 const SubobjectDesignator &
Designator = LVal.Designator;
12103 llvm::APInt APEndOffset;
12104 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12116 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12122 int64_t ElemsRemaining;
12125 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12126 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12127 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12129 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12132 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12142 EvalInfo &Info, uint64_t &Size) {
12149 SpeculativeEvaluationRAII SpeculativeEval(Info);
12150 IgnoreSideEffectsRAII Fold(Info);
12158 LVal.setFrom(Info.Ctx, RVal);
12166 if (LVal.getLValueOffset().isNegative()) {
12177 if (EndOffset <= LVal.getLValueOffset())
12180 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12184bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12185 if (!IsConstantEvaluatedBuiltinCall(E))
12186 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12203 Info.FFDiag(E->
getArg(0));
12209 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12210 "Bit widths must be the same");
12217bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
12218 unsigned BuiltinOp) {
12219 switch (BuiltinOp) {
12223 case Builtin::BI__builtin_dynamic_object_size:
12224 case Builtin::BI__builtin_object_size: {
12228 assert(
Type <= 3 &&
"unexpected type");
12239 switch (Info.EvalMode) {
12240 case EvalInfo::EM_ConstantExpression:
12241 case EvalInfo::EM_ConstantFold:
12242 case EvalInfo::EM_IgnoreSideEffects:
12245 case EvalInfo::EM_ConstantExpressionUnevaluated:
12250 llvm_unreachable(
"unexpected EvalMode");
12253 case Builtin::BI__builtin_os_log_format_buffer_size: {
12259 case Builtin::BI__builtin_is_aligned: {
12267 Ptr.setFrom(Info.Ctx, Src);
12273 assert(Alignment.isPowerOf2());
12286 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
12290 assert(Src.
isInt());
12291 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
12293 case Builtin::BI__builtin_align_up: {
12301 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12302 Src.
getInt().isUnsigned());
12303 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12304 return Success(AlignedVal, E);
12306 case Builtin::BI__builtin_align_down: {
12315 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12316 return Success(AlignedVal, E);
12319 case Builtin::BI__builtin_bitreverse8:
12320 case Builtin::BI__builtin_bitreverse16:
12321 case Builtin::BI__builtin_bitreverse32:
12322 case Builtin::BI__builtin_bitreverse64: {
12327 return Success(Val.reverseBits(), E);
12330 case Builtin::BI__builtin_bswap16:
12331 case Builtin::BI__builtin_bswap32:
12332 case Builtin::BI__builtin_bswap64: {
12337 return Success(Val.byteSwap(), E);
12340 case Builtin::BI__builtin_classify_type:
12343 case Builtin::BI__builtin_clrsb:
12344 case Builtin::BI__builtin_clrsbl:
12345 case Builtin::BI__builtin_clrsbll: {
12350 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
12353 case Builtin::BI__builtin_clz:
12354 case Builtin::BI__builtin_clzl:
12355 case Builtin::BI__builtin_clzll:
12356 case Builtin::BI__builtin_clzs:
12357 case Builtin::BI__builtin_clzg:
12358 case Builtin::BI__lzcnt16:
12359 case Builtin::BI__lzcnt:
12360 case Builtin::BI__lzcnt64: {
12365 std::optional<APSInt> Fallback;
12366 if (BuiltinOp == Builtin::BI__builtin_clzg && E->
getNumArgs() > 1) {
12370 Fallback = FallbackTemp;
12375 return Success(*Fallback, E);
12380 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
12381 BuiltinOp != Builtin::BI__lzcnt &&
12382 BuiltinOp != Builtin::BI__lzcnt64;
12384 if (ZeroIsUndefined)
12388 return Success(Val.countl_zero(), E);
12391 case Builtin::BI__builtin_constant_p: {
12401 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
12405 case Builtin::BI__builtin_is_constant_evaluated: {
12406 const auto *
Callee = Info.CurrentCall->getCallee();
12407 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
12408 (Info.CallStackDepth == 1 ||
12409 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
12410 Callee->getIdentifier() &&
12411 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
12413 if (Info.EvalStatus.Diag)
12414 Info.report((Info.CallStackDepth == 1)
12416 : Info.CurrentCall->getCallRange().getBegin(),
12417 diag::warn_is_constant_evaluated_always_true_constexpr)
12418 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
12419 :
"std::is_constant_evaluated");
12422 return Success(Info.InConstantContext, E);
12425 case Builtin::BI__builtin_ctz:
12426 case Builtin::BI__builtin_ctzl:
12427 case Builtin::BI__builtin_ctzll:
12428 case Builtin::BI__builtin_ctzs:
12429 case Builtin::BI__builtin_ctzg: {
12434 std::optional<APSInt> Fallback;
12435 if (BuiltinOp == Builtin::BI__builtin_ctzg && E->
getNumArgs() > 1) {
12439 Fallback = FallbackTemp;
12444 return Success(*Fallback, E);
12449 return Success(Val.countr_zero(), E);
12452 case Builtin::BI__builtin_eh_return_data_regno: {
12454 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
12458 case Builtin::BI__builtin_expect:
12459 case Builtin::BI__builtin_expect_with_probability:
12460 return Visit(E->
getArg(0));
12462 case Builtin::BI__builtin_ffs:
12463 case Builtin::BI__builtin_ffsl:
12464 case Builtin::BI__builtin_ffsll: {
12469 unsigned N = Val.countr_zero();
12470 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
12473 case Builtin::BI__builtin_fpclassify: {
12478 switch (Val.getCategory()) {
12479 case APFloat::fcNaN: Arg = 0;
break;
12480 case APFloat::fcInfinity: Arg = 1;
break;
12481 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
12482 case APFloat::fcZero: Arg = 4;
break;
12484 return Visit(E->
getArg(Arg));
12487 case Builtin::BI__builtin_isinf_sign: {
12490 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
12493 case Builtin::BI__builtin_isinf: {
12496 Success(Val.isInfinity() ? 1 : 0, E);
12499 case Builtin::BI__builtin_isfinite: {
12502 Success(Val.isFinite() ? 1 : 0, E);
12505 case Builtin::BI__builtin_isnan: {
12508 Success(Val.isNaN() ? 1 : 0, E);
12511 case Builtin::BI__builtin_isnormal: {
12514 Success(Val.isNormal() ? 1 : 0, E);
12517 case Builtin::BI__builtin_issubnormal: {
12520 Success(Val.isDenormal() ? 1 : 0, E);
12523 case Builtin::BI__builtin_iszero: {
12526 Success(Val.isZero() ? 1 : 0, E);
12529 case Builtin::BI__builtin_issignaling: {
12532 Success(Val.isSignaling() ? 1 : 0, E);
12535 case Builtin::BI__builtin_isfpclass: {
12539 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
12542 Success((Val.classify() & Test) ? 1 : 0, E);
12545 case Builtin::BI__builtin_parity:
12546 case Builtin::BI__builtin_parityl:
12547 case Builtin::BI__builtin_parityll: {
12552 return Success(Val.popcount() % 2, E);
12555 case Builtin::BI__builtin_popcount:
12556 case Builtin::BI__builtin_popcountl:
12557 case Builtin::BI__builtin_popcountll:
12558 case Builtin::BI__builtin_popcountg:
12559 case Builtin::BI__popcnt16:
12560 case Builtin::BI__popcnt:
12561 case Builtin::BI__popcnt64: {
12566 return Success(Val.popcount(), E);
12569 case Builtin::BI__builtin_rotateleft8:
12570 case Builtin::BI__builtin_rotateleft16:
12571 case Builtin::BI__builtin_rotateleft32:
12572 case Builtin::BI__builtin_rotateleft64:
12573 case Builtin::BI_rotl8:
12574 case Builtin::BI_rotl16:
12575 case Builtin::BI_rotl:
12576 case Builtin::BI_lrotl:
12577 case Builtin::BI_rotl64: {
12583 return Success(Val.rotl(Amt.urem(Val.getBitWidth())), E);
12586 case Builtin::BI__builtin_rotateright8:
12587 case Builtin::BI__builtin_rotateright16:
12588 case Builtin::BI__builtin_rotateright32:
12589 case Builtin::BI__builtin_rotateright64:
12590 case Builtin::BI_rotr8:
12591 case Builtin::BI_rotr16:
12592 case Builtin::BI_rotr:
12593 case Builtin::BI_lrotr:
12594 case Builtin::BI_rotr64: {
12600 return Success(Val.rotr(Amt.urem(Val.getBitWidth())), E);
12603 case Builtin::BIstrlen:
12604 case Builtin::BIwcslen:
12606 if (Info.getLangOpts().CPlusPlus11)
12607 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
12609 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12611 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12613 case Builtin::BI__builtin_strlen:
12614 case Builtin::BI__builtin_wcslen: {
12623 case Builtin::BIstrcmp:
12624 case Builtin::BIwcscmp:
12625 case Builtin::BIstrncmp:
12626 case Builtin::BIwcsncmp:
12627 case Builtin::BImemcmp:
12628 case Builtin::BIbcmp:
12629 case Builtin::BIwmemcmp:
12631 if (Info.getLangOpts().CPlusPlus11)
12632 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
12634 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12636 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12638 case Builtin::BI__builtin_strcmp:
12639 case Builtin::BI__builtin_wcscmp:
12640 case Builtin::BI__builtin_strncmp:
12641 case Builtin::BI__builtin_wcsncmp:
12642 case Builtin::BI__builtin_memcmp:
12643 case Builtin::BI__builtin_bcmp:
12644 case Builtin::BI__builtin_wmemcmp: {
12645 LValue String1, String2;
12651 if (BuiltinOp != Builtin::BIstrcmp &&
12652 BuiltinOp != Builtin::BIwcscmp &&
12653 BuiltinOp != Builtin::BI__builtin_strcmp &&
12654 BuiltinOp != Builtin::BI__builtin_wcscmp) {
12658 MaxLength = N.getZExtValue();
12662 if (MaxLength == 0u)
12665 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
12666 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
12667 String1.Designator.Invalid || String2.Designator.Invalid)
12670 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
12671 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
12673 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
12674 BuiltinOp == Builtin::BIbcmp ||
12675 BuiltinOp == Builtin::BI__builtin_memcmp ||
12676 BuiltinOp == Builtin::BI__builtin_bcmp;
12678 assert(IsRawByte ||
12679 (Info.Ctx.hasSameUnqualifiedType(
12681 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
12688 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
12689 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
12690 << CharTy1 << CharTy2;
12694 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
12697 Char1.
isInt() && Char2.isInt();
12699 const auto &AdvanceElems = [&] {
12705 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
12706 BuiltinOp != Builtin::BIwmemcmp &&
12707 BuiltinOp != Builtin::BI__builtin_memcmp &&
12708 BuiltinOp != Builtin::BI__builtin_bcmp &&
12709 BuiltinOp != Builtin::BI__builtin_wmemcmp);
12710 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
12711 BuiltinOp == Builtin::BIwcsncmp ||
12712 BuiltinOp == Builtin::BIwmemcmp ||
12713 BuiltinOp == Builtin::BI__builtin_wcscmp ||
12714 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
12715 BuiltinOp == Builtin::BI__builtin_wmemcmp;
12717 for (; MaxLength; --MaxLength) {
12719 if (!ReadCurElems(Char1, Char2))
12727 if (StopAtNull && !Char1.
getInt())
12729 assert(!(StopAtNull && !Char2.
getInt()));
12730 if (!AdvanceElems())
12737 case Builtin::BI__atomic_always_lock_free:
12738 case Builtin::BI__atomic_is_lock_free:
12739 case Builtin::BI__c11_atomic_is_lock_free: {
12755 if (
Size.isPowerOfTwo()) {
12757 unsigned InlineWidthBits =
12758 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
12759 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
12760 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
12771 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
12778 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
12781 case Builtin::BI__builtin_addcb:
12782 case Builtin::BI__builtin_addcs:
12783 case Builtin::BI__builtin_addc:
12784 case Builtin::BI__builtin_addcl:
12785 case Builtin::BI__builtin_addcll:
12786 case Builtin::BI__builtin_subcb:
12787 case Builtin::BI__builtin_subcs:
12788 case Builtin::BI__builtin_subc:
12789 case Builtin::BI__builtin_subcl:
12790 case Builtin::BI__builtin_subcll: {
12791 LValue CarryOutLValue;
12792 APSInt LHS, RHS, CarryIn, CarryOut, Result;
12803 bool FirstOverflowed =
false;
12804 bool SecondOverflowed =
false;
12805 switch (BuiltinOp) {
12807 llvm_unreachable(
"Invalid value for BuiltinOp");
12808 case Builtin::BI__builtin_addcb:
12809 case Builtin::BI__builtin_addcs:
12810 case Builtin::BI__builtin_addc:
12811 case Builtin::BI__builtin_addcl:
12812 case Builtin::BI__builtin_addcll:
12814 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
12816 case Builtin::BI__builtin_subcb:
12817 case Builtin::BI__builtin_subcs:
12818 case Builtin::BI__builtin_subc:
12819 case Builtin::BI__builtin_subcl:
12820 case Builtin::BI__builtin_subcll:
12822 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
12828 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
12834 case Builtin::BI__builtin_add_overflow:
12835 case Builtin::BI__builtin_sub_overflow:
12836 case Builtin::BI__builtin_mul_overflow:
12837 case Builtin::BI__builtin_sadd_overflow:
12838 case Builtin::BI__builtin_uadd_overflow:
12839 case Builtin::BI__builtin_uaddl_overflow:
12840 case Builtin::BI__builtin_uaddll_overflow:
12841 case Builtin::BI__builtin_usub_overflow:
12842 case Builtin::BI__builtin_usubl_overflow:
12843 case Builtin::BI__builtin_usubll_overflow:
12844 case Builtin::BI__builtin_umul_overflow:
12845 case Builtin::BI__builtin_umull_overflow:
12846 case Builtin::BI__builtin_umulll_overflow:
12847 case Builtin::BI__builtin_saddl_overflow:
12848 case Builtin::BI__builtin_saddll_overflow:
12849 case Builtin::BI__builtin_ssub_overflow:
12850 case Builtin::BI__builtin_ssubl_overflow:
12851 case Builtin::BI__builtin_ssubll_overflow:
12852 case Builtin::BI__builtin_smul_overflow:
12853 case Builtin::BI__builtin_smull_overflow:
12854 case Builtin::BI__builtin_smulll_overflow: {
12855 LValue ResultLValue;
12865 bool DidOverflow =
false;
12868 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
12869 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
12870 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
12871 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
12873 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
12875 uint64_t LHSSize = LHS.getBitWidth();
12876 uint64_t RHSSize = RHS.getBitWidth();
12877 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
12878 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
12884 if (IsSigned && !AllSigned)
12887 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
12888 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
12889 Result =
APSInt(MaxBits, !IsSigned);
12893 switch (BuiltinOp) {
12895 llvm_unreachable(
"Invalid value for BuiltinOp");
12896 case Builtin::BI__builtin_add_overflow:
12897 case Builtin::BI__builtin_sadd_overflow:
12898 case Builtin::BI__builtin_saddl_overflow:
12899 case Builtin::BI__builtin_saddll_overflow:
12900 case Builtin::BI__builtin_uadd_overflow:
12901 case Builtin::BI__builtin_uaddl_overflow:
12902 case Builtin::BI__builtin_uaddll_overflow:
12903 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
12904 : LHS.uadd_ov(RHS, DidOverflow);
12906 case Builtin::BI__builtin_sub_overflow:
12907 case Builtin::BI__builtin_ssub_overflow:
12908 case Builtin::BI__builtin_ssubl_overflow:
12909 case Builtin::BI__builtin_ssubll_overflow:
12910 case Builtin::BI__builtin_usub_overflow:
12911 case Builtin::BI__builtin_usubl_overflow:
12912 case Builtin::BI__builtin_usubll_overflow:
12913 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
12914 : LHS.usub_ov(RHS, DidOverflow);
12916 case Builtin::BI__builtin_mul_overflow:
12917 case Builtin::BI__builtin_smul_overflow:
12918 case Builtin::BI__builtin_smull_overflow:
12919 case Builtin::BI__builtin_smulll_overflow:
12920 case Builtin::BI__builtin_umul_overflow:
12921 case Builtin::BI__builtin_umull_overflow:
12922 case Builtin::BI__builtin_umulll_overflow:
12923 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
12924 : LHS.umul_ov(RHS, DidOverflow);
12930 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
12931 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
12932 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
12938 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
12941 if (!APSInt::isSameValue(Temp, Result))
12942 DidOverflow =
true;
12949 return Success(DidOverflow, E);
12957 const LValue &LV) {
12960 if (!LV.getLValueBase())
12965 if (!LV.getLValueDesignator().Invalid &&
12966 !LV.getLValueDesignator().isOnePastTheEnd())
12971 QualType Ty = getType(LV.getLValueBase());
12976 if (LV.getLValueDesignator().Invalid)
12982 return LV.getLValueOffset() == Size;
12992class DataRecursiveIntBinOpEvaluator {
12993 struct EvalResult {
12995 bool Failed =
false;
12997 EvalResult() =
default;
12999 void swap(EvalResult &RHS) {
13001 Failed = RHS.Failed;
13002 RHS.Failed =
false;
13008 EvalResult LHSResult;
13009 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13012 Job(Job &&) =
default;
13014 void startSpeculativeEval(EvalInfo &Info) {
13015 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13019 SpeculativeEvaluationRAII SpecEvalRAII;
13024 IntExprEvaluator &IntEval;
13029 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13030 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13045 EvalResult PrevResult;
13046 while (!Queue.empty())
13047 process(PrevResult);
13049 if (PrevResult.Failed)
return false;
13051 FinalResult.
swap(PrevResult.Val);
13057 return IntEval.Success(
Value, E, Result);
13060 return IntEval.Success(
Value, E, Result);
13063 return IntEval.Error(E);
13066 return IntEval.Error(E, D);
13070 return Info.CCEDiag(E, D);
13074 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
13075 bool &SuppressRHSDiags);
13077 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13080 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
13081 Result.Failed = !
Evaluate(Result.Val, Info, E);
13086 void process(EvalResult &Result);
13088 void enqueue(
const Expr *E) {
13090 Queue.resize(Queue.size()+1);
13091 Queue.back().E = E;
13092 Queue.back().Kind = Job::AnyExprKind;
13098bool DataRecursiveIntBinOpEvaluator::
13099 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
13100 bool &SuppressRHSDiags) {
13103 if (LHSResult.Failed)
13104 return Info.noteSideEffect();
13113 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
13114 Success(LHSAsBool, E, LHSResult.Val);
13118 LHSResult.Failed =
true;
13122 if (!Info.noteSideEffect())
13128 SuppressRHSDiags =
true;
13137 if (LHSResult.Failed && !Info.noteFailure())
13148 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
13150 uint64_t Offset64 = Offset.getQuantity();
13151 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
13153 : Offset64 + Index64);
13156bool DataRecursiveIntBinOpEvaluator::
13157 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13160 if (RHSResult.Failed)
13162 Result = RHSResult.Val;
13167 bool lhsResult, rhsResult;
13174 return Success(lhsResult || rhsResult, E, Result);
13176 return Success(lhsResult && rhsResult, E, Result);
13182 if (rhsResult == (E->
getOpcode() == BO_LOr))
13183 return Success(rhsResult, E, Result);
13193 if (LHSResult.Failed || RHSResult.Failed)
13196 const APValue &LHSVal = LHSResult.Val;
13197 const APValue &RHSVal = RHSResult.Val;
13221 if (!LHSExpr || !RHSExpr)
13223 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
13224 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
13225 if (!LHSAddrExpr || !RHSAddrExpr)
13231 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
13250void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
13251 Job &job = Queue.back();
13253 switch (job.Kind) {
13254 case Job::AnyExprKind: {
13255 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
13256 if (shouldEnqueue(Bop)) {
13257 job.Kind = Job::BinOpKind;
13258 enqueue(Bop->getLHS());
13263 EvaluateExpr(job.E, Result);
13268 case Job::BinOpKind: {
13270 bool SuppressRHSDiags =
false;
13271 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
13275 if (SuppressRHSDiags)
13276 job.startSpeculativeEval(Info);
13277 job.LHSResult.swap(Result);
13278 job.Kind = Job::BinOpVisitedLHSKind;
13283 case Job::BinOpVisitedLHSKind: {
13287 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
13293 llvm_unreachable(
"Invalid Job::Kind!");
13297enum class CmpResult {
13306template <
class SuccessCB,
class AfterCB>
13309 SuccessCB &&
Success, AfterCB &&DoAfter) {
13314 "unsupported binary expression evaluation");
13315 auto Error = [&](
const Expr *E) {
13316 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
13330 if (!LHSOK && !Info.noteFailure())
13335 return Success(CmpResult::Less, E);
13337 return Success(CmpResult::Greater, E);
13338 return Success(CmpResult::Equal, E);
13342 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
13343 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
13346 if (!LHSOK && !Info.noteFailure())
13351 return Success(CmpResult::Less, E);
13353 return Success(CmpResult::Greater, E);
13354 return Success(CmpResult::Equal, E);
13358 ComplexValue LHS, RHS;
13367 LHS.makeComplexFloat();
13368 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
13373 if (!LHSOK && !Info.noteFailure())
13379 RHS.makeComplexFloat();
13380 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
13384 if (LHS.isComplexFloat()) {
13385 APFloat::cmpResult CR_r =
13386 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
13387 APFloat::cmpResult CR_i =
13388 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
13389 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
13390 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
13392 assert(IsEquality &&
"invalid complex comparison");
13393 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
13394 LHS.getComplexIntImag() == RHS.getComplexIntImag();
13395 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
13401 APFloat RHS(0.0), LHS(0.0);
13404 if (!LHSOK && !Info.noteFailure())
13411 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
13412 if (!Info.InConstantContext &&
13413 APFloatCmpResult == APFloat::cmpUnordered &&
13416 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
13419 auto GetCmpRes = [&]() {
13420 switch (APFloatCmpResult) {
13421 case APFloat::cmpEqual:
13422 return CmpResult::Equal;
13423 case APFloat::cmpLessThan:
13424 return CmpResult::Less;
13425 case APFloat::cmpGreaterThan:
13426 return CmpResult::Greater;
13427 case APFloat::cmpUnordered:
13428 return CmpResult::Unordered;
13430 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
13432 return Success(GetCmpRes(), E);
13436 LValue LHSValue, RHSValue;
13439 if (!LHSOK && !Info.noteFailure())
13448 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
13449 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
13450 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
13451 Info.FFDiag(E, DiagID)
13458 return DiagComparison(
13459 diag::note_constexpr_pointer_comparison_unspecified);
13465 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
13466 (!RHSValue.Base && !RHSValue.Offset.isZero()))
13467 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
13474 LHSValue.Base && RHSValue.Base)
13475 return DiagComparison(diag::note_constexpr_literal_comparison);
13479 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
13483 if (LHSValue.Base && LHSValue.Offset.isZero() &&
13485 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13487 if (RHSValue.Base && RHSValue.Offset.isZero() &&
13489 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13495 return DiagComparison(
13496 diag::note_constexpr_pointer_comparison_zero_sized);
13497 return Success(CmpResult::Unequal, E);
13500 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
13501 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
13503 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
13504 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
13514 Info.CCEDiag(E, diag::note_constexpr_void_comparison);
13524 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
13525 bool WasArrayIndex;
13527 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
13534 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
13535 Mismatch < RHSDesignator.Entries.size()) {
13536 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
13537 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
13539 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
13541 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
13542 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
13545 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
13546 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
13551 diag::note_constexpr_pointer_comparison_differing_access)
13559 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
13562 assert(PtrSize <= 64 &&
"Unexpected pointer width");
13563 uint64_t Mask = ~0ULL >> (64 - PtrSize);
13564 CompareLHS &= Mask;
13565 CompareRHS &= Mask;
13570 if (!LHSValue.Base.isNull() && IsRelational) {
13571 QualType BaseTy = getType(LHSValue.Base);
13574 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
13575 uint64_t OffsetLimit = Size.getQuantity();
13576 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
13580 if (CompareLHS < CompareRHS)
13581 return Success(CmpResult::Less, E);
13582 if (CompareLHS > CompareRHS)
13583 return Success(CmpResult::Greater, E);
13584 return Success(CmpResult::Equal, E);
13588 assert(IsEquality &&
"unexpected member pointer operation");
13591 MemberPtr LHSValue, RHSValue;
13594 if (!LHSOK && !Info.noteFailure())
13602 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
13603 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
13604 << LHSValue.getDecl();
13607 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
13608 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
13609 << RHSValue.getDecl();
13616 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
13617 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
13618 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
13623 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
13624 if (MD->isVirtual())
13625 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
13626 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
13627 if (MD->isVirtual())
13628 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
13634 bool Equal = LHSValue == RHSValue;
13635 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
13640 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
13648 return Success(CmpResult::Equal, E);
13661 case CmpResult::Unequal:
13662 llvm_unreachable(
"should never produce Unequal for three-way comparison");
13663 case CmpResult::Less:
13664 CCR = ComparisonCategoryResult::Less;
13666 case CmpResult::Equal:
13667 CCR = ComparisonCategoryResult::Equal;
13669 case CmpResult::Greater:
13670 CCR = ComparisonCategoryResult::Greater;
13672 case CmpResult::Unordered:
13673 CCR = ComparisonCategoryResult::Unordered;
13687 ConstantExprKind::Normal);
13690 return ExprEvaluatorBaseTy::VisitBinCmp(E);
13694bool RecordExprEvaluator::VisitCXXParenListInitExpr(
13696 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
13699bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
13704 if (!Info.noteFailure())
13708 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
13709 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
13713 "DataRecursiveIntBinOpEvaluator should have handled integral types");
13719 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
13720 "should only produce Unequal for equality comparisons");
13721 bool IsEqual = CR == CmpResult::Equal,
13722 IsLess = CR == CmpResult::Less,
13723 IsGreater = CR == CmpResult::Greater;
13727 llvm_unreachable(
"unsupported binary operator");
13730 return Success(IsEqual == (Op == BO_EQ), E);
13734 return Success(IsGreater, E);
13736 return Success(IsEqual || IsLess, E);
13738 return Success(IsEqual || IsGreater, E);
13742 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
13751 LValue LHSValue, RHSValue;
13754 if (!LHSOK && !Info.noteFailure())
13764 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
13766 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
13767 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
13768 if (!LHSExpr || !RHSExpr)
13770 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
13771 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
13772 if (!LHSAddrExpr || !RHSAddrExpr)
13780 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
13781 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
13783 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
13784 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
13790 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
13793 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
13805 if (ElementSize.
isZero()) {
13806 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
13823 APSInt TrueResult = (LHS - RHS) / ElemSize;
13824 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
13826 if (Result.extend(65) != TrueResult &&
13832 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
13837bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
13840 case UETT_PreferredAlignOf:
13841 case UETT_AlignOf: {
13850 case UETT_VecStep: {
13866 case UETT_DataSizeOf:
13867 case UETT_SizeOf: {
13876 E->
getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
13877 : SizeOfType::SizeOf)) {
13882 case UETT_OpenMPRequiredSimdAlign:
13885 Info.Ctx.toCharUnitsFromBits(
13889 case UETT_VectorElements: {
13897 if (Info.InConstantContext)
13898 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
13905 llvm_unreachable(
"unknown expr/type trait");
13908bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
13914 for (
unsigned i = 0; i != n; ++i) {
13922 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
13926 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
13927 Result += IdxResult.getSExtValue() * ElementSize;
13940 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
13947 llvm_unreachable(
"dependent __builtin_offsetof");
13963 CurrentType = BaseSpec->
getType();
13977bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
13993 if (!Result.isInt())
return Error(E);
13996 if (Info.checkingForUndefinedBehavior())
13997 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
13998 diag::warn_integer_constant_overflow)
14012 if (!Result.isInt())
return Error(E);
14013 return Success(~Result.getInt(), E);
14026bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14032 case CK_BaseToDerived:
14033 case CK_DerivedToBase:
14034 case CK_UncheckedDerivedToBase:
14037 case CK_ArrayToPointerDecay:
14038 case CK_FunctionToPointerDecay:
14039 case CK_NullToPointer:
14040 case CK_NullToMemberPointer:
14041 case CK_BaseToDerivedMemberPointer:
14042 case CK_DerivedToBaseMemberPointer:
14043 case CK_ReinterpretMemberPointer:
14044 case CK_ConstructorConversion:
14045 case CK_IntegralToPointer:
14047 case CK_VectorSplat:
14048 case CK_IntegralToFloating:
14049 case CK_FloatingCast:
14050 case CK_CPointerToObjCPointerCast:
14051 case CK_BlockPointerToObjCPointerCast:
14052 case CK_AnyPointerToBlockPointerCast:
14053 case CK_ObjCObjectLValueCast:
14054 case CK_FloatingRealToComplex:
14055 case CK_FloatingComplexToReal:
14056 case CK_FloatingComplexCast:
14057 case CK_FloatingComplexToIntegralComplex:
14058 case CK_IntegralRealToComplex:
14059 case CK_IntegralComplexCast:
14060 case CK_IntegralComplexToFloatingComplex:
14061 case CK_BuiltinFnToFnPtr:
14062 case CK_ZeroToOCLOpaqueType:
14063 case CK_NonAtomicToAtomic:
14064 case CK_AddressSpaceConversion:
14065 case CK_IntToOCLSampler:
14066 case CK_FloatingToFixedPoint:
14067 case CK_FixedPointToFloating:
14068 case CK_FixedPointCast:
14069 case CK_IntegralToFixedPoint:
14070 case CK_MatrixCast:
14071 case CK_HLSLVectorTruncation:
14072 llvm_unreachable(
"invalid cast kind for integral value");
14076 case CK_LValueBitCast:
14077 case CK_ARCProduceObject:
14078 case CK_ARCConsumeObject:
14079 case CK_ARCReclaimReturnedObject:
14080 case CK_ARCExtendBlockObject:
14081 case CK_CopyAndAutoreleaseBlockObject:
14084 case CK_UserDefinedConversion:
14085 case CK_LValueToRValue:
14086 case CK_AtomicToNonAtomic:
14088 case CK_LValueToRValueBitCast:
14089 case CK_HLSLArrayRValue:
14090 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14092 case CK_MemberPointerToBoolean:
14093 case CK_PointerToBoolean:
14094 case CK_IntegralToBoolean:
14095 case CK_FloatingToBoolean:
14096 case CK_BooleanToSignedIntegral:
14097 case CK_FloatingComplexToBoolean:
14098 case CK_IntegralComplexToBoolean: {
14103 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
14105 return Success(IntResult, E);
14108 case CK_FixedPointToIntegral: {
14109 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
14113 llvm::APSInt Result = Src.convertToInt(
14114 Info.Ctx.getIntWidth(DestType),
14121 case CK_FixedPointToBoolean: {
14124 if (!
Evaluate(Val, Info, SubExpr))
14129 case CK_IntegralCast: {
14130 if (!Visit(SubExpr))
14133 if (!Result.isInt()) {
14139 if (Result.isAddrLabelDiff())
14140 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
14142 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
14145 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
14146 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
14149 bool ConstexprVar =
true;
14156 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
14157 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
14180 (
Max.slt(Result.getInt().getSExtValue()) ||
14181 Min.sgt(Result.getInt().getSExtValue())))
14182 Info.Ctx.getDiagnostics().Report(
14183 E->
getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range)
14184 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
14185 <<
Max.getSExtValue() << ED;
14187 Max.ult(Result.getInt().getZExtValue()))
14188 Info.Ctx.getDiagnostics().Report(
14189 E->
getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range)
14190 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
14191 <<
Max.getZExtValue() << ED;
14196 Result.getInt()), E);
14199 case CK_PointerToIntegral: {
14200 CCEDiag(E, diag::note_constexpr_invalid_cast)
14201 << 2 << Info.Ctx.getLangOpts().CPlusPlus << E->
getSourceRange();
14207 if (LV.getLValueBase()) {
14212 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
14215 LV.Designator.setInvalid();
14216 LV.moveInto(Result);
14223 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
14224 llvm_unreachable(
"Can't cast this!");
14229 case CK_IntegralComplexToReal: {
14233 return Success(
C.getComplexIntReal(), E);
14236 case CK_FloatingToIntegral: {
14248 llvm_unreachable(
"unknown cast resulting in integral value");
14251bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
14256 if (!LV.isComplexInt())
14258 return Success(LV.getComplexIntReal(), E);
14264bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
14269 if (!LV.isComplexInt())
14271 return Success(LV.getComplexIntImag(), E);
14278bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
14282bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
14286bool IntExprEvaluator::VisitConceptSpecializationExpr(
14291bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
14295bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
14305 if (!Result.isFixedPoint())
14308 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
14322bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14326 "Expected destination type to be a fixed point type");
14327 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
14330 case CK_FixedPointCast: {
14331 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
14335 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
14337 if (Info.checkingForUndefinedBehavior())
14338 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14339 diag::warn_fixedpoint_constant_overflow)
14340 << Result.toString() << E->
getType();
14346 case CK_IntegralToFixedPoint: {
14352 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
14353 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14356 if (Info.checkingForUndefinedBehavior())
14357 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14358 diag::warn_fixedpoint_constant_overflow)
14359 << IntResult.toString() << E->
getType();
14364 return Success(IntResult, E);
14366 case CK_FloatingToFixedPoint: {
14372 APFixedPoint Result = APFixedPoint::getFromFloatValue(
14373 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14376 if (Info.checkingForUndefinedBehavior())
14377 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14378 diag::warn_fixedpoint_constant_overflow)
14379 << Result.toString() << E->
getType();
14387 case CK_LValueToRValue:
14388 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14394bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
14396 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
14400 FixedPointSemantics ResultFXSema =
14401 Info.Ctx.getFixedPointSemantics(E->
getType());
14403 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
14406 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
14410 bool OpOverflow =
false, ConversionOverflow =
false;
14411 APFixedPoint Result(LHSFX.getSemantics());
14414 Result = LHSFX.
add(RHSFX, &OpOverflow)
14415 .convert(ResultFXSema, &ConversionOverflow);
14419 Result = LHSFX.sub(RHSFX, &OpOverflow)
14420 .convert(ResultFXSema, &ConversionOverflow);
14424 Result = LHSFX.mul(RHSFX, &OpOverflow)
14425 .convert(ResultFXSema, &ConversionOverflow);
14429 if (RHSFX.getValue() == 0) {
14430 Info.FFDiag(E, diag::note_expr_divide_by_zero);
14433 Result = LHSFX.div(RHSFX, &OpOverflow)
14434 .convert(ResultFXSema, &ConversionOverflow);
14439 FixedPointSemantics LHSSema = LHSFX.getSemantics();
14440 llvm::APSInt RHSVal = RHSFX.getValue();
14443 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
14444 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
14448 if (RHSVal.isNegative())
14449 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
14450 else if (Amt != RHSVal)
14451 Info.CCEDiag(E, diag::note_constexpr_large_shift)
14452 << RHSVal << E->
getType() << ShiftBW;
14455 Result = LHSFX.shl(Amt, &OpOverflow);
14457 Result = LHSFX.shr(Amt, &OpOverflow);
14463 if (OpOverflow || ConversionOverflow) {
14464 if (Info.checkingForUndefinedBehavior())
14465 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14466 diag::warn_fixedpoint_constant_overflow)
14467 << Result.toString() << E->
getType();
14479class FloatExprEvaluator
14480 :
public ExprEvaluatorBase<FloatExprEvaluator> {
14483 FloatExprEvaluator(EvalInfo &info, APFloat &result)
14484 : ExprEvaluatorBaseTy(info), Result(result) {}
14487 Result =
V.getFloat();
14491 bool ZeroInitialization(
const Expr *E) {
14492 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
14496 bool VisitCallExpr(
const CallExpr *E);
14501 bool VisitCastExpr(
const CastExpr *E);
14513 return FloatExprEvaluator(Info, Result).Visit(E);
14520 llvm::APFloat &Result) {
14522 if (!S)
return false;
14529 if (S->getString().empty())
14530 fill = llvm::APInt(32, 0);
14531 else if (S->getString().getAsInteger(0, fill))
14536 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14538 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14546 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14548 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14554bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
14555 if (!IsConstantEvaluatedBuiltinCall(E))
14556 return ExprEvaluatorBaseTy::VisitCallExpr(E);
14562 case Builtin::BI__builtin_huge_val:
14563 case Builtin::BI__builtin_huge_valf:
14564 case Builtin::BI__builtin_huge_vall:
14565 case Builtin::BI__builtin_huge_valf16:
14566 case Builtin::BI__builtin_huge_valf128:
14567 case Builtin::BI__builtin_inf:
14568 case Builtin::BI__builtin_inff:
14569 case Builtin::BI__builtin_infl:
14570 case Builtin::BI__builtin_inff16:
14571 case Builtin::BI__builtin_inff128: {
14572 const llvm::fltSemantics &Sem =
14573 Info.Ctx.getFloatTypeSemantics(E->
getType());
14574 Result = llvm::APFloat::getInf(Sem);
14578 case Builtin::BI__builtin_nans:
14579 case Builtin::BI__builtin_nansf:
14580 case Builtin::BI__builtin_nansl:
14581 case Builtin::BI__builtin_nansf16:
14582 case Builtin::BI__builtin_nansf128:
14588 case Builtin::BI__builtin_nan:
14589 case Builtin::BI__builtin_nanf:
14590 case Builtin::BI__builtin_nanl:
14591 case Builtin::BI__builtin_nanf16:
14592 case Builtin::BI__builtin_nanf128:
14600 case Builtin::BI__builtin_fabs:
14601 case Builtin::BI__builtin_fabsf:
14602 case Builtin::BI__builtin_fabsl:
14603 case Builtin::BI__builtin_fabsf128:
14612 if (Result.isNegative())
14613 Result.changeSign();
14616 case Builtin::BI__arithmetic_fence:
14623 case Builtin::BI__builtin_copysign:
14624 case Builtin::BI__builtin_copysignf:
14625 case Builtin::BI__builtin_copysignl:
14626 case Builtin::BI__builtin_copysignf128: {
14631 Result.copySign(RHS);
14635 case Builtin::BI__builtin_fmax:
14636 case Builtin::BI__builtin_fmaxf:
14637 case Builtin::BI__builtin_fmaxl:
14638 case Builtin::BI__builtin_fmaxf16:
14639 case Builtin::BI__builtin_fmaxf128: {
14646 if (Result.isZero() && RHS.isZero() && Result.isNegative())
14648 else if (Result.isNaN() || RHS > Result)
14653 case Builtin::BI__builtin_fmin:
14654 case Builtin::BI__builtin_fminf:
14655 case Builtin::BI__builtin_fminl:
14656 case Builtin::BI__builtin_fminf16:
14657 case Builtin::BI__builtin_fminf128: {
14664 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
14666 else if (Result.isNaN() || RHS < Result)
14673bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
14678 Result = CV.FloatReal;
14685bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
14690 Result = CV.FloatImag;
14695 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
14696 Result = llvm::APFloat::getZero(Sem);
14700bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
14702 default:
return Error(E);
14711 Result.changeSign();
14716bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
14718 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
14722 if (!LHSOK && !Info.noteFailure())
14728bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
14733bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14738 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14740 case CK_IntegralToFloating: {
14743 Info.Ctx.getLangOpts());
14746 IntResult, E->
getType(), Result);
14749 case CK_FixedPointToFloating: {
14750 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
14754 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
14758 case CK_FloatingCast: {
14759 if (!Visit(SubExpr))
14765 case CK_FloatingComplexToReal: {
14769 Result =
V.getComplexFloatReal();
14780class ComplexExprEvaluator
14781 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
14782 ComplexValue &Result;
14785 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
14786 : ExprEvaluatorBaseTy(info), Result(Result) {}
14793 bool ZeroInitialization(
const Expr *E);
14800 bool VisitCastExpr(
const CastExpr *E);
14804 bool VisitCallExpr(
const CallExpr *E);
14812 return ComplexExprEvaluator(Info, Result).Visit(E);
14815bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
14818 Result.makeComplexFloat();
14819 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
14820 Result.FloatReal =
Zero;
14821 Result.FloatImag =
Zero;
14823 Result.makeComplexInt();
14824 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
14825 Result.IntReal =
Zero;
14826 Result.IntImag =
Zero;
14831bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
14835 Result.makeComplexFloat();
14836 APFloat &Imag = Result.FloatImag;
14840 Result.FloatReal =
APFloat(Imag.getSemantics());
14844 "Unexpected imaginary literal.");
14846 Result.makeComplexInt();
14847 APSInt &Imag = Result.IntImag;
14851 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
14856bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14860 case CK_BaseToDerived:
14861 case CK_DerivedToBase:
14862 case CK_UncheckedDerivedToBase:
14865 case CK_ArrayToPointerDecay:
14866 case CK_FunctionToPointerDecay:
14867 case CK_NullToPointer:
14868 case CK_NullToMemberPointer:
14869 case CK_BaseToDerivedMemberPointer:
14870 case CK_DerivedToBaseMemberPointer:
14871 case CK_MemberPointerToBoolean:
14872 case CK_ReinterpretMemberPointer:
14873 case CK_ConstructorConversion:
14874 case CK_IntegralToPointer:
14875 case CK_PointerToIntegral:
14876 case CK_PointerToBoolean:
14878 case CK_VectorSplat:
14879 case CK_IntegralCast:
14880 case CK_BooleanToSignedIntegral:
14881 case CK_IntegralToBoolean:
14882 case CK_IntegralToFloating:
14883 case CK_FloatingToIntegral:
14884 case CK_FloatingToBoolean:
14885 case CK_FloatingCast:
14886 case CK_CPointerToObjCPointerCast:
14887 case CK_BlockPointerToObjCPointerCast:
14888 case CK_AnyPointerToBlockPointerCast:
14889 case CK_ObjCObjectLValueCast:
14890 case CK_FloatingComplexToReal:
14891 case CK_FloatingComplexToBoolean:
14892 case CK_IntegralComplexToReal:
14893 case CK_IntegralComplexToBoolean:
14894 case CK_ARCProduceObject:
14895 case CK_ARCConsumeObject:
14896 case CK_ARCReclaimReturnedObject:
14897 case CK_ARCExtendBlockObject:
14898 case CK_CopyAndAutoreleaseBlockObject:
14899 case CK_BuiltinFnToFnPtr:
14900 case CK_ZeroToOCLOpaqueType:
14901 case CK_NonAtomicToAtomic:
14902 case CK_AddressSpaceConversion:
14903 case CK_IntToOCLSampler:
14904 case CK_FloatingToFixedPoint:
14905 case CK_FixedPointToFloating:
14906 case CK_FixedPointCast:
14907 case CK_FixedPointToBoolean:
14908 case CK_FixedPointToIntegral:
14909 case CK_IntegralToFixedPoint:
14910 case CK_MatrixCast:
14911 case CK_HLSLVectorTruncation:
14912 llvm_unreachable(
"invalid cast kind for complex value");
14914 case CK_LValueToRValue:
14915 case CK_AtomicToNonAtomic:
14917 case CK_LValueToRValueBitCast:
14918 case CK_HLSLArrayRValue:
14919 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14922 case CK_LValueBitCast:
14923 case CK_UserDefinedConversion:
14926 case CK_FloatingRealToComplex: {
14927 APFloat &Real = Result.FloatReal;
14931 Result.makeComplexFloat();
14932 Result.FloatImag =
APFloat(Real.getSemantics());
14936 case CK_FloatingComplexCast: {
14948 case CK_FloatingComplexToIntegralComplex: {
14955 Result.makeComplexInt();
14957 To, Result.IntReal) &&
14959 To, Result.IntImag);
14962 case CK_IntegralRealToComplex: {
14963 APSInt &Real = Result.IntReal;
14967 Result.makeComplexInt();
14968 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
14972 case CK_IntegralComplexCast: {
14985 case CK_IntegralComplexToFloatingComplex: {
14990 Info.Ctx.getLangOpts());
14994 Result.makeComplexFloat();
14996 To, Result.FloatReal) &&
14998 To, Result.FloatImag);
15002 llvm_unreachable(
"unknown cast resulting in complex value");
15005bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
15007 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
15011 bool LHSReal =
false, RHSReal =
false;
15016 APFloat &Real = Result.FloatReal;
15019 Result.makeComplexFloat();
15020 Result.FloatImag =
APFloat(Real.getSemantics());
15023 LHSOK = Visit(E->
getLHS());
15025 if (!LHSOK && !Info.noteFailure())
15031 APFloat &Real = RHS.FloatReal;
15034 RHS.makeComplexFloat();
15035 RHS.FloatImag =
APFloat(Real.getSemantics());
15039 assert(!(LHSReal && RHSReal) &&
15040 "Cannot have both operands of a complex operation be real.");
15042 default:
return Error(E);
15044 if (Result.isComplexFloat()) {
15045 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
15046 APFloat::rmNearestTiesToEven);
15048 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15050 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
15051 APFloat::rmNearestTiesToEven);
15053 Result.getComplexIntReal() += RHS.getComplexIntReal();
15054 Result.getComplexIntImag() += RHS.getComplexIntImag();
15058 if (Result.isComplexFloat()) {
15059 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
15060 APFloat::rmNearestTiesToEven);
15062 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15063 Result.getComplexFloatImag().changeSign();
15064 }
else if (!RHSReal) {
15065 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
15066 APFloat::rmNearestTiesToEven);
15069 Result.getComplexIntReal() -= RHS.getComplexIntReal();
15070 Result.getComplexIntImag() -= RHS.getComplexIntImag();
15074 if (Result.isComplexFloat()) {
15079 ComplexValue LHS = Result;
15080 APFloat &A = LHS.getComplexFloatReal();
15081 APFloat &B = LHS.getComplexFloatImag();
15082 APFloat &
C = RHS.getComplexFloatReal();
15083 APFloat &D = RHS.getComplexFloatImag();
15084 APFloat &ResR = Result.getComplexFloatReal();
15085 APFloat &ResI = Result.getComplexFloatImag();
15087 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
15090 }
else if (RHSReal) {
15102 if (ResR.isNaN() && ResI.isNaN()) {
15103 bool Recalc =
false;
15104 if (A.isInfinity() || B.isInfinity()) {
15105 A = APFloat::copySign(
15106 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
15107 B = APFloat::copySign(
15108 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
15110 C = APFloat::copySign(
APFloat(
C.getSemantics()),
C);
15112 D = APFloat::copySign(
APFloat(D.getSemantics()), D);
15115 if (
C.isInfinity() || D.isInfinity()) {
15116 C = APFloat::copySign(
15117 APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
C);
15118 D = APFloat::copySign(
15119 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
15121 A = APFloat::copySign(
APFloat(A.getSemantics()), A);
15123 B = APFloat::copySign(
APFloat(B.getSemantics()), B);
15126 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
15127 AD.isInfinity() || BC.isInfinity())) {
15129 A = APFloat::copySign(
APFloat(A.getSemantics()), A);
15131 B = APFloat::copySign(
APFloat(B.getSemantics()), B);
15133 C = APFloat::copySign(
APFloat(
C.getSemantics()),
C);
15135 D = APFloat::copySign(
APFloat(D.getSemantics()), D);
15139 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
15140 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
15145 ComplexValue LHS = Result;
15146 Result.getComplexIntReal() =
15147 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
15148 LHS.getComplexIntImag() * RHS.getComplexIntImag());
15149 Result.getComplexIntImag() =
15150 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
15151 LHS.getComplexIntImag() * RHS.getComplexIntReal());
15155 if (Result.isComplexFloat()) {
15160 ComplexValue LHS = Result;
15161 APFloat &A = LHS.getComplexFloatReal();
15162 APFloat &B = LHS.getComplexFloatImag();
15163 APFloat &
C = RHS.getComplexFloatReal();
15164 APFloat &D = RHS.getComplexFloatImag();
15165 APFloat &ResR = Result.getComplexFloatReal();
15166 APFloat &ResI = Result.getComplexFloatImag();
15173 B = APFloat::getZero(A.getSemantics());
15177 if (MaxCD.isFinite()) {
15178 DenomLogB =
ilogb(MaxCD);
15179 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
15180 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
15183 ResR =
scalbn((A *
C + B * D) / Denom, -DenomLogB,
15184 APFloat::rmNearestTiesToEven);
15185 ResI =
scalbn((B *
C - A * D) / Denom, -DenomLogB,
15186 APFloat::rmNearestTiesToEven);
15187 if (ResR.isNaN() && ResI.isNaN()) {
15188 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
15189 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
15190 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
15191 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
15193 A = APFloat::copySign(
15194 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
15195 B = APFloat::copySign(
15196 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
15197 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
15198 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
15199 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
15200 C = APFloat::copySign(
15201 APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
C);
15202 D = APFloat::copySign(
15203 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
15204 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
15205 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
15210 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
15211 return Error(E, diag::note_expr_divide_by_zero);
15213 ComplexValue LHS = Result;
15214 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
15215 RHS.getComplexIntImag() * RHS.getComplexIntImag();
15216 Result.getComplexIntReal() =
15217 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
15218 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
15219 Result.getComplexIntImag() =
15220 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
15221 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
15229bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
15243 if (Result.isComplexFloat()) {
15244 Result.getComplexFloatReal().changeSign();
15245 Result.getComplexFloatImag().changeSign();
15248 Result.getComplexIntReal() = -Result.getComplexIntReal();
15249 Result.getComplexIntImag() = -Result.getComplexIntImag();
15253 if (Result.isComplexFloat())
15254 Result.getComplexFloatImag().changeSign();
15256 Result.getComplexIntImag() = -Result.getComplexIntImag();
15261bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15264 Result.makeComplexFloat();
15270 Result.makeComplexInt();
15278 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
15281bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
15282 if (!IsConstantEvaluatedBuiltinCall(E))
15283 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15286 case Builtin::BI__builtin_complex:
15287 Result.makeComplexFloat();
15305class AtomicExprEvaluator :
15306 public ExprEvaluatorBase<AtomicExprEvaluator> {
15307 const LValue *
This;
15310 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
15311 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
15318 bool ZeroInitialization(
const Expr *E) {
15327 bool VisitCastExpr(
const CastExpr *E) {
15330 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15331 case CK_NullToPointer:
15333 return ZeroInitialization(E);
15334 case CK_NonAtomicToAtomic:
15336 :
Evaluate(Result, Info, E->getSubExpr());
15346 return AtomicExprEvaluator(Info, This, Result).Visit(E);
15355class VoidExprEvaluator
15356 :
public ExprEvaluatorBase<VoidExprEvaluator> {
15358 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
15362 bool ZeroInitialization(
const Expr *E) {
return true; }
15364 bool VisitCastExpr(
const CastExpr *E) {
15367 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15374 bool VisitCallExpr(
const CallExpr *E) {
15375 if (!IsConstantEvaluatedBuiltinCall(E))
15376 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15379 case Builtin::BI__assume:
15380 case Builtin::BI__builtin_assume:
15384 case Builtin::BI__builtin_operator_delete:
15396bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
15398 if (Info.SpeculativeEvaluationDepth)
15403 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
15404 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
15413 if (
Pointer.Designator.Invalid)
15417 if (
Pointer.isNullPointer()) {
15421 if (!Info.getLangOpts().CPlusPlus20)
15422 Info.CCEDiag(E, diag::note_constexpr_new);
15436 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
15445 if (VirtualDelete &&
15447 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
15448 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
15454 (*Alloc)->Value, AllocType))
15462 Info.FFDiag(E, diag::note_constexpr_double_delete);
15472 return VoidExprEvaluator(Info).Visit(E);
15488 LV.moveInto(Result);
15493 if (!IntExprEvaluator(Info, Result).Visit(E))
15499 LV.moveInto(Result);
15501 llvm::APFloat F(0.0);
15509 C.moveInto(Result);
15511 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
15516 P.moveInto(Result);
15521 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
15528 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
15533 if (!Info.getLangOpts().CPlusPlus11)
15534 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
15539 QualType Unqual =
T.getAtomicUnqualifiedType();
15543 E, Unqual, ScopeKind::FullExpression, LV);
15551 }
else if (Info.getLangOpts().CPlusPlus11) {
15552 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
15555 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15566 const Expr *E,
bool AllowNonLiteralTypes) {
15581 QualType Unqual =
T.getAtomicUnqualifiedType();
15602 if (Info.EnableNewConstInterp) {
15603 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
15606 ConstantExprKind::Normal);
15615 LV.setFrom(Info.Ctx, Result);
15622 ConstantExprKind::Normal) &&
15632 L->getType()->isUnsignedIntegerType()));
15637 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
15643 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
15644 if (CE->hasAPValueResult()) {
15645 Result.Val = CE->getAPValueResult();
15720 bool InConstantContext)
const {
15721 assert(!isValueDependent() &&
15722 "Expression evaluator can't be called on a dependent expression.");
15723 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
15724 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
15725 Info.InConstantContext = InConstantContext;
15726 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
15730 bool InConstantContext)
const {
15731 assert(!isValueDependent() &&
15732 "Expression evaluator can't be called on a dependent expression.");
15733 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
15741 bool InConstantContext)
const {
15742 assert(!isValueDependent() &&
15743 "Expression evaluator can't be called on a dependent expression.");
15744 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
15745 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
15746 Info.InConstantContext = InConstantContext;
15747 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
15752 bool InConstantContext)
const {
15753 assert(!isValueDependent() &&
15754 "Expression evaluator can't be called on a dependent expression.");
15755 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
15756 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
15757 Info.InConstantContext = InConstantContext;
15758 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
15763 bool InConstantContext)
const {
15764 assert(!isValueDependent() &&
15765 "Expression evaluator can't be called on a dependent expression.");
15767 if (!getType()->isRealFloatingType())
15770 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
15782 bool InConstantContext)
const {
15783 assert(!isValueDependent() &&
15784 "Expression evaluator can't be called on a dependent expression.");
15786 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
15787 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
15788 Info.InConstantContext = InConstantContext;
15791 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
15792 Result.HasSideEffects ||
15795 ConstantExprKind::Normal, CheckedTemps))
15798 LV.moveInto(Result.Val);
15805 bool IsConstantDestruction) {
15806 EvalInfo Info(Ctx, EStatus,
15807 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
15808 : EvalInfo::EM_ConstantFold);
15809 Info.setEvaluatingDecl(
Base, DestroyedValue,
15810 EvalInfo::EvaluatingDeclKind::Dtor);
15811 Info.InConstantContext = IsConstantDestruction;
15820 if (!Info.discardCleanups())
15821 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
15828 assert(!isValueDependent() &&
15829 "Expression evaluator can't be called on a dependent expression.");
15834 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
15835 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
15836 EvalInfo Info(Ctx, Result, EM);
15837 Info.InConstantContext =
true;
15839 if (Info.EnableNewConstInterp) {
15840 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val))
15843 getStorageType(Ctx,
this), Result.Val, Kind);
15848 if (Kind == ConstantExprKind::ClassTemplateArgument)
15856 Info.setEvaluatingDecl(
Base, Result.Val);
15858 if (Info.EnableNewConstInterp) {
15859 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
15868 FullExpressionRAII
Scope(Info);
15870 Result.HasSideEffects || !
Scope.destroy())
15873 if (!Info.discardCleanups())
15874 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
15885 if (Kind == ConstantExprKind::ClassTemplateArgument &&
15888 Result.HasSideEffects)) {
15900 bool IsConstantInitialization)
const {
15901 assert(!isValueDependent() &&
15902 "Expression evaluator can't be called on a dependent expression.");
15904 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
15906 llvm::raw_string_ostream OS(Name);
15912 EStatus.
Diag = &Notes;
15914 EvalInfo Info(Ctx, EStatus,
15915 (IsConstantInitialization &&
15917 ? EvalInfo::EM_ConstantExpression
15918 : EvalInfo::EM_ConstantFold);
15919 Info.setEvaluatingDecl(VD,
Value);
15920 Info.InConstantContext = IsConstantInitialization;
15925 if (Info.EnableNewConstInterp) {
15926 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
15927 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
15931 ConstantExprKind::Normal);
15946 FullExpressionRAII
Scope(Info);
15949 EStatus.HasSideEffects)
15955 Info.performLifetimeExtension();
15957 if (!Info.discardCleanups())
15958 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
15962 ConstantExprKind::Normal) &&
15969 EStatus.
Diag = &Notes;
15973 bool IsConstantDestruction = hasConstantInitialization();
15979 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
15980 DestroyedValue = *getEvaluatedValue();
15985 getType(), getLocation(), EStatus,
15986 IsConstantDestruction) ||
15990 ensureEvaluatedStmt()->HasConstantDestruction =
true;
15997 assert(!isValueDependent() &&
15998 "Expression evaluator can't be called on a dependent expression.");
16007 assert(!isValueDependent() &&
16008 "Expression evaluator can't be called on a dependent expression.");
16010 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
16013 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16014 Info.InConstantContext =
true;
16018 assert(Result &&
"Could not evaluate expression");
16019 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16021 return EVResult.Val.getInt();
16026 assert(!isValueDependent() &&
16027 "Expression evaluator can't be called on a dependent expression.");
16029 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
16032 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16033 Info.InConstantContext =
true;
16034 Info.CheckingForUndefinedBehavior =
true;
16038 assert(Result &&
"Could not evaluate expression");
16039 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16041 return EVResult.Val.getInt();
16045 assert(!isValueDependent() &&
16046 "Expression evaluator can't be called on a dependent expression.");
16048 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
16052 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16053 Info.CheckingForUndefinedBehavior =
true;
16086 IK_ICEIfUnevaluated,
16102static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
16107 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16109 Info.InConstantContext =
true;
16118 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
16123#define ABSTRACT_STMT(Node)
16124#define STMT(Node, Base) case Expr::Node##Class:
16125#define EXPR(Node, Base)
16126#include "clang/AST/StmtNodes.inc"
16127 case Expr::PredefinedExprClass:
16128 case Expr::FloatingLiteralClass:
16129 case Expr::ImaginaryLiteralClass:
16130 case Expr::StringLiteralClass:
16131 case Expr::ArraySubscriptExprClass:
16132 case Expr::MatrixSubscriptExprClass:
16133 case Expr::ArraySectionExprClass:
16134 case Expr::OMPArrayShapingExprClass:
16135 case Expr::OMPIteratorExprClass:
16136 case Expr::MemberExprClass:
16137 case Expr::CompoundAssignOperatorClass:
16138 case Expr::CompoundLiteralExprClass:
16139 case Expr::ExtVectorElementExprClass:
16140 case Expr::DesignatedInitExprClass:
16141 case Expr::ArrayInitLoopExprClass:
16142 case Expr::ArrayInitIndexExprClass:
16143 case Expr::NoInitExprClass:
16144 case Expr::DesignatedInitUpdateExprClass:
16145 case Expr::ImplicitValueInitExprClass:
16146 case Expr::ParenListExprClass:
16147 case Expr::VAArgExprClass:
16148 case Expr::AddrLabelExprClass:
16149 case Expr::StmtExprClass:
16150 case Expr::CXXMemberCallExprClass:
16151 case Expr::CUDAKernelCallExprClass:
16152 case Expr::CXXAddrspaceCastExprClass:
16153 case Expr::CXXDynamicCastExprClass:
16154 case Expr::CXXTypeidExprClass:
16155 case Expr::CXXUuidofExprClass:
16156 case Expr::MSPropertyRefExprClass:
16157 case Expr::MSPropertySubscriptExprClass:
16158 case Expr::CXXNullPtrLiteralExprClass:
16159 case Expr::UserDefinedLiteralClass:
16160 case Expr::CXXThisExprClass:
16161 case Expr::CXXThrowExprClass:
16162 case Expr::CXXNewExprClass:
16163 case Expr::CXXDeleteExprClass:
16164 case Expr::CXXPseudoDestructorExprClass:
16165 case Expr::UnresolvedLookupExprClass:
16166 case Expr::TypoExprClass:
16167 case Expr::RecoveryExprClass:
16168 case Expr::DependentScopeDeclRefExprClass:
16169 case Expr::CXXConstructExprClass:
16170 case Expr::CXXInheritedCtorInitExprClass:
16171 case Expr::CXXStdInitializerListExprClass:
16172 case Expr::CXXBindTemporaryExprClass:
16173 case Expr::ExprWithCleanupsClass:
16174 case Expr::CXXTemporaryObjectExprClass:
16175 case Expr::CXXUnresolvedConstructExprClass:
16176 case Expr::CXXDependentScopeMemberExprClass:
16177 case Expr::UnresolvedMemberExprClass:
16178 case Expr::ObjCStringLiteralClass:
16179 case Expr::ObjCBoxedExprClass:
16180 case Expr::ObjCArrayLiteralClass:
16181 case Expr::ObjCDictionaryLiteralClass:
16182 case Expr::ObjCEncodeExprClass:
16183 case Expr::ObjCMessageExprClass:
16184 case Expr::ObjCSelectorExprClass:
16185 case Expr::ObjCProtocolExprClass:
16186 case Expr::ObjCIvarRefExprClass:
16187 case Expr::ObjCPropertyRefExprClass:
16188 case Expr::ObjCSubscriptRefExprClass:
16189 case Expr::ObjCIsaExprClass:
16190 case Expr::ObjCAvailabilityCheckExprClass:
16191 case Expr::ShuffleVectorExprClass:
16192 case Expr::ConvertVectorExprClass:
16193 case Expr::BlockExprClass:
16194 case Expr::NoStmtClass:
16195 case Expr::OpaqueValueExprClass:
16196 case Expr::PackExpansionExprClass:
16197 case Expr::SubstNonTypeTemplateParmPackExprClass:
16198 case Expr::FunctionParmPackExprClass:
16199 case Expr::AsTypeExprClass:
16200 case Expr::ObjCIndirectCopyRestoreExprClass:
16201 case Expr::MaterializeTemporaryExprClass:
16202 case Expr::PseudoObjectExprClass:
16203 case Expr::AtomicExprClass:
16204 case Expr::LambdaExprClass:
16205 case Expr::CXXFoldExprClass:
16206 case Expr::CoawaitExprClass:
16207 case Expr::DependentCoawaitExprClass:
16208 case Expr::CoyieldExprClass:
16209 case Expr::SYCLUniqueStableNameExprClass:
16210 case Expr::CXXParenListInitExprClass:
16213 case Expr::InitListExprClass: {
16219 if (cast<InitListExpr>(E)->getNumInits() == 1)
16220 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
16224 case Expr::SizeOfPackExprClass:
16225 case Expr::GNUNullExprClass:
16226 case Expr::SourceLocExprClass:
16229 case Expr::PackIndexingExprClass:
16230 return CheckICE(cast<PackIndexingExpr>(E)->getSelectedExpr(), Ctx);
16232 case Expr::SubstNonTypeTemplateParmExprClass:
16234 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
16236 case Expr::ConstantExprClass:
16237 return CheckICE(cast<ConstantExpr>(E)->getSubExpr(), Ctx);
16239 case Expr::ParenExprClass:
16240 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
16241 case Expr::GenericSelectionExprClass:
16242 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
16243 case Expr::IntegerLiteralClass:
16244 case Expr::FixedPointLiteralClass:
16245 case Expr::CharacterLiteralClass:
16246 case Expr::ObjCBoolLiteralExprClass:
16247 case Expr::CXXBoolLiteralExprClass:
16248 case Expr::CXXScalarValueInitExprClass:
16249 case Expr::TypeTraitExprClass:
16250 case Expr::ConceptSpecializationExprClass:
16251 case Expr::RequiresExprClass:
16252 case Expr::ArrayTypeTraitExprClass:
16253 case Expr::ExpressionTraitExprClass:
16254 case Expr::CXXNoexceptExprClass:
16256 case Expr::CallExprClass:
16257 case Expr::CXXOperatorCallExprClass: {
16261 const CallExpr *CE = cast<CallExpr>(E);
16266 case Expr::CXXRewrittenBinaryOperatorClass:
16267 return CheckICE(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm(),
16269 case Expr::DeclRefExprClass: {
16270 const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
16271 if (isa<EnumConstantDecl>(D))
16283 const VarDecl *VD = dyn_cast<VarDecl>(D);
16290 case Expr::UnaryOperatorClass: {
16313 llvm_unreachable(
"invalid unary operator class");
16315 case Expr::OffsetOfExprClass: {
16324 case Expr::UnaryExprOrTypeTraitExprClass: {
16326 if ((Exp->
getKind() == UETT_SizeOf) &&
16331 case Expr::BinaryOperatorClass: {
16376 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
16379 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
16380 if (REval.isSigned() && REval.isAllOnes()) {
16382 if (LEval.isMinSignedValue())
16383 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
16391 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
16392 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
16398 return Worst(LHSResult, RHSResult);
16404 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
16414 return Worst(LHSResult, RHSResult);
16417 llvm_unreachable(
"invalid binary operator kind");
16419 case Expr::ImplicitCastExprClass:
16420 case Expr::CStyleCastExprClass:
16421 case Expr::CXXFunctionalCastExprClass:
16422 case Expr::CXXStaticCastExprClass:
16423 case Expr::CXXReinterpretCastExprClass:
16424 case Expr::CXXConstCastExprClass:
16425 case Expr::ObjCBridgedCastExprClass: {
16426 const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
16427 if (isa<ExplicitCastExpr>(E)) {
16432 APSInt IgnoredVal(DestWidth, !DestSigned);
16437 if (FL->getValue().convertToInteger(IgnoredVal,
16438 llvm::APFloat::rmTowardZero,
16439 &Ignored) & APFloat::opInvalidOp)
16444 switch (cast<CastExpr>(E)->getCastKind()) {
16445 case CK_LValueToRValue:
16446 case CK_AtomicToNonAtomic:
16447 case CK_NonAtomicToAtomic:
16449 case CK_IntegralToBoolean:
16450 case CK_IntegralCast:
16456 case Expr::BinaryConditionalOperatorClass: {
16459 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
16461 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
16462 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
16463 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
16465 return FalseResult;
16467 case Expr::ConditionalOperatorClass: {
16475 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
16478 if (CondResult.Kind == IK_NotICE)
16484 if (TrueResult.Kind == IK_NotICE)
16486 if (FalseResult.Kind == IK_NotICE)
16487 return FalseResult;
16488 if (CondResult.Kind == IK_ICEIfUnevaluated)
16490 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
16496 return FalseResult;
16499 case Expr::CXXDefaultArgExprClass:
16500 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
16501 case Expr::CXXDefaultInitExprClass:
16502 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
16503 case Expr::ChooseExprClass: {
16504 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
16506 case Expr::BuiltinBitCastExprClass: {
16507 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(E)))
16509 return CheckICE(cast<CastExpr>(E)->getSubExpr(), Ctx);
16513 llvm_unreachable(
"Invalid StmtClass!");
16519 llvm::APSInt *
Value,
16530 if (!Result.isInt()) {
16541 assert(!isValueDependent() &&
16542 "Expression evaluator can't be called on a dependent expression.");
16544 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
16550 if (D.Kind != IK_ICE) {
16551 if (Loc) *Loc = D.Loc;
16557std::optional<llvm::APSInt>
16559 if (isValueDependent()) {
16561 return std::nullopt;
16569 return std::nullopt;
16572 if (!isIntegerConstantExpr(Ctx, Loc))
16573 return std::nullopt;
16581 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
16582 Info.InConstantContext =
true;
16585 llvm_unreachable(
"ICE cannot be evaluated!");
16591 assert(!isValueDependent() &&
16592 "Expression evaluator can't be called on a dependent expression.");
16594 return CheckICE(
this, Ctx).Kind == IK_ICE;
16599 assert(!isValueDependent() &&
16600 "Expression evaluator can't be called on a dependent expression.");
16609 Status.Diag = &Diags;
16610 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16617 Info.discardCleanups() && !Status.HasSideEffects;
16619 if (!Diags.empty()) {
16620 IsConstExpr =
false;
16621 if (Loc) *Loc = Diags[0].first;
16622 }
else if (!IsConstExpr) {
16624 if (Loc) *Loc = getExprLoc();
16627 return IsConstExpr;
16633 const Expr *This)
const {
16634 assert(!isValueDependent() &&
16635 "Expression evaluator can't be called on a dependent expression.");
16637 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
16639 llvm::raw_string_ostream OS(Name);
16646 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
16647 Info.InConstantContext =
true;
16650 const LValue *ThisPtr =
nullptr;
16653 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
16654 assert(MD &&
"Don't provide `this` for non-methods.");
16655 assert(MD->isImplicitObjectMemberFunction() &&
16656 "Don't provide `this` for methods without an implicit object.");
16658 if (!This->isValueDependent() &&
16660 !Info.EvalStatus.HasSideEffects)
16661 ThisPtr = &ThisVal;
16665 Info.EvalStatus.HasSideEffects =
false;
16668 CallRef
Call = Info.CurrentCall->createCall(Callee);
16671 unsigned Idx = I - Args.begin();
16672 if (Idx >= Callee->getNumParams())
16674 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
16675 if ((*I)->isValueDependent() ||
16677 Info.EvalStatus.HasSideEffects) {
16679 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
16685 Info.EvalStatus.HasSideEffects =
false;
16690 Info.discardCleanups();
16691 Info.EvalStatus.HasSideEffects =
false;
16694 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
16697 FullExpressionRAII
Scope(Info);
16699 !Info.EvalStatus.HasSideEffects;
16711 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
16713 llvm::raw_string_ostream OS(Name);
16720 Status.Diag = &Diags;
16722 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
16723 Info.InConstantContext =
true;
16724 Info.CheckingPotentialConstantExpression =
true;
16727 if (Info.EnableNewConstInterp) {
16728 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
16729 return Diags.empty();
16739 This.set({&VIE, Info.CurrentCall->Index});
16747 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
16753 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
16757 return Diags.empty();
16765 "Expression evaluator can't be called on a dependent expression.");
16768 Status.Diag = &Diags;
16771 EvalInfo::EM_ConstantExpressionUnevaluated);
16772 Info.InConstantContext =
true;
16773 Info.CheckingPotentialConstantExpression =
true;
16777 nullptr, CallRef());
16781 return Diags.empty();
16785 unsigned Type)
const {
16786 if (!getType()->isPointerType())
16790 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
16807 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
16808 String.getLValueBase().dyn_cast<
const Expr *>())) {
16809 StringRef Str = S->getBytes();
16810 int64_t Off = String.Offset.getQuantity();
16811 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
16812 S->getCharByteWidth() == 1 &&
16814 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
16815 Str = Str.substr(Off);
16817 StringRef::size_type Pos = Str.find(0);
16818 if (Pos != StringRef::npos)
16819 Str = Str.substr(0, Pos);
16821 Result = Str.size();
16829 for (uint64_t Strlen = 0; ; ++Strlen) {
16844 const Expr *SizeExpression,
16848 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16849 Info.InConstantContext =
true;
16851 FullExpressionRAII
Scope(Info);
16856 uint64_t Size = SizeValue.getZExtValue();
16862 for (uint64_t I = 0; I < Size; ++I) {
16869 Result.push_back(
static_cast<char>(
C.getExtValue()));
16873 if (!
Scope.destroy())
16884 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
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)
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 isValidIndeterminateAccess(AccessKinds AK)
Is this kind of axcess valid on an indeterminate object value?
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
static CharUnits GetAlignOfType(EvalInfo &Info, QualType T, UnaryExprOrTypeTrait ExprKind)
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize.
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static bool IsLiteralLValue(const LValue &Value)
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *This, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
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 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 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 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 CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E, UnaryExprOrTypeTrait ExprKind)
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.
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 IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false)
Evaluate the arguments to a function call.
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static bool IsNoOpCall(const CallExpr *E)
Should this call expression be treated as a no-op?
static bool isModification(AccessKinds AK)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const CallExpr *Call, llvm::APInt &Result)
Attempts to compute the number of bytes available at the pointer returned by a function with the allo...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static 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)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, SourceLocation *Loc)
Evaluate an expression as a C++11 integral constant expression.
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
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 EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result, EvalInfo &Info)
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned.
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static bool 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 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.
Defines the clang::TypeLoc interface and its subclasses.
__DEVICE__ long long abs(long long __n)
llvm::APInt getValue() const
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.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getArraySize() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
QualType getRecordType(const RecordDecl *Decl) const
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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.
const TargetInfo & getTargetInfo() const
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.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
uint64_t getValue() const
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 condnition evaluates to false;...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
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".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
bool isComparisonOp() const
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
A binding in a decomposition declaration.
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const BlockDecl * getBlockDecl() const
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.
const Expr * getSubExpr() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
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.
Expr * getExpr()
Get the initialization expression that will be used.
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
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.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
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...
CXXMethodDecl * getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find if RD declares a function that overrides this function, and if so, return it.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
Represents a list-initialization with parenthesis.
ArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
base_class_iterator bases_end()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
capture_const_iterator captures_end() const
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
capture_const_iterator captures_begin() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
A rewritten comparison expression that was originally written using operator syntax.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
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...
QualType getTypeOperand(ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
bool isTypeOperand() const
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Expr ** getArgs()
Retrieve the call arguments.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
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.
unsigned getValue() const
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
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].
const Expr * getInitializer() const
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.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
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...
APValue getAPValueResult() const
bool hasAPValueResult() const
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
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
A decomposition declaration.
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
void getValueRange(llvm::APInt &Max, llvm::APInt &Min) const
Calculates the [Min,Max) values the enum can store based on the NumPositiveBits and NumNegativeBits.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
@ NPC_NeverValueDependent
Specifies that the expression should never be value-dependent.
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.
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
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.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr, SourceLocation *Loc=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
An expression trait intrinsic.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
const Expr * getBase() const
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
unsigned getBitWidthValue(const ASTContext &Ctx) const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
const Expr * getSubExpr() const
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.
QualType getReturnType() 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 isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
bool isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Represents a C11 generic selection.
Expr * getResultExpr()
Return the result expression of this controlling expression.
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....
const Expr * getSubExpr() const
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.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
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.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
bool isExpressibleAsConstantInitializer() const
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.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
A partial diagnostic which we might know in advance that we are not going to emit.
Expr * getSelectedExpr() const
ParenExpr - This represents a parethesized expression, e.g.
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
PointerType - C99 6.7.5.1 - Pointer Declarators.
[C99 6.4.2.2] - A predefined identifier such as func.
StringLiteral * getFunctionName()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool isConstant(const ASTContext &Ctx) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Base for LValueReferenceType and RValueReferenceType.
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
Represents an expression that computes the length of a parameter pack.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
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;}).
CompoundStmt * getSubStmt()
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, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
SourceLocation getBeginLoc() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
A template parameter object.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
The base class of the type hierarchy.
bool isStructureType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool 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
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
const RecordType * getAsStructureType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
bool ReturnValue(const T &V, APValue &R)
Convert a value to an APValue.
bool NE(InterpState &S, CodePtr OpPC)
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ NonNull
Values of this type can never be null.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
ActionResult< Expr * > ExprResult
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Success
Template argument deduction was successful.
@ None
The alignment was not explicit in code.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
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)