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) ||
2710 isa<ConvertVectorExpr>(E)) &&
2711 "HandleFloatToFloatCast has been checked with only CastExpr, "
2712 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2713 "the new expression or address the root cause of this usage.");
2715 APFloat::opStatus St;
2716 APFloat
Value = Result;
2718 St = Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2725 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2731 Result =
Value.getBoolValue();
2738 QualType DestType, APFloat &Result) {
2739 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2741 APFloat::opStatus St = Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2747 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2749 if (!
Value.isInt()) {
2753 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2759 unsigned OldBitWidth = Int.getBitWidth();
2761 if (NewBitWidth < OldBitWidth)
2762 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2769template<
typename Operation>
2772 unsigned BitWidth, Operation Op,
2774 if (LHS.isUnsigned()) {
2775 Result = Op(LHS, RHS);
2779 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2780 Result =
Value.trunc(LHS.getBitWidth());
2781 if (Result.extend(BitWidth) !=
Value) {
2782 if (Info.checkingForUndefinedBehavior())
2783 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2784 diag::warn_integer_constant_overflow)
2785 <<
toString(Result, 10, Result.isSigned(),
false,
2797 bool HandleOverflowResult =
true;
2804 std::multiplies<APSInt>(), Result);
2807 std::plus<APSInt>(), Result);
2810 std::minus<APSInt>(), Result);
2811 case BO_And: Result = LHS & RHS;
return true;
2812 case BO_Xor: Result = LHS ^ RHS;
return true;
2813 case BO_Or: Result = LHS | RHS;
return true;
2817 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2823 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2824 LHS.isMinSignedValue())
2826 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2827 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2828 return HandleOverflowResult;
2830 if (Info.getLangOpts().OpenCL)
2832 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2833 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2835 else if (RHS.isSigned() && RHS.isNegative()) {
2838 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2845 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2847 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2848 << RHS << E->
getType() << LHS.getBitWidth();
2849 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2854 if (LHS.isNegative())
2855 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2856 else if (LHS.countl_zero() < SA)
2857 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2863 if (Info.getLangOpts().OpenCL)
2865 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2866 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2868 else if (RHS.isSigned() && RHS.isNegative()) {
2871 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2878 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2880 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2881 << RHS << E->
getType() << LHS.getBitWidth();
2886 case BO_LT: Result = LHS < RHS;
return true;
2887 case BO_GT: Result = LHS > RHS;
return true;
2888 case BO_LE: Result = LHS <= RHS;
return true;
2889 case BO_GE: Result = LHS >= RHS;
return true;
2890 case BO_EQ: Result = LHS == RHS;
return true;
2891 case BO_NE: Result = LHS != RHS;
return true;
2893 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2900 const APFloat &RHS) {
2902 APFloat::opStatus St;
2908 St = LHS.multiply(RHS, RM);
2911 St = LHS.add(RHS, RM);
2914 St = LHS.subtract(RHS, RM);
2920 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2921 St = LHS.divide(RHS, RM);
2930 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2931 return Info.noteUndefinedBehavior();
2939 const APInt &RHSValue, APInt &Result) {
2940 bool LHS = (LHSValue != 0);
2941 bool RHS = (RHSValue != 0);
2943 if (Opcode == BO_LAnd)
2944 Result = LHS && RHS;
2946 Result = LHS || RHS;
2951 const APFloat &RHSValue, APInt &Result) {
2952 bool LHS = !LHSValue.isZero();
2953 bool RHS = !RHSValue.isZero();
2955 if (Opcode == BO_LAnd)
2956 Result = LHS && RHS;
2958 Result = LHS || RHS;
2964 const APValue &RHSValue, APInt &Result) {
2968 RHSValue.
getInt(), Result);
2974template <
typename APTy>
2977 const APTy &RHSValue, APInt &Result) {
2980 llvm_unreachable(
"unsupported binary operator");
2982 Result = (LHSValue == RHSValue);
2985 Result = (LHSValue != RHSValue);
2988 Result = (LHSValue < RHSValue);
2991 Result = (LHSValue > RHSValue);
2994 Result = (LHSValue <= RHSValue);
2997 Result = (LHSValue >= RHSValue);
3011 const APValue &RHSValue, APInt &Result) {
3015 RHSValue.
getInt(), Result);
3026 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3027 "Operation not supported on vector types");
3031 QualType EltTy = VT->getElementType();
3038 "A vector result that isn't a vector OR uncalculated LValue");
3044 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3048 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3053 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3063 RHSElt.
getInt(), EltResult);
3069 ResultElements.emplace_back(EltResult);
3074 "Mismatched LHS/RHS/Result Type");
3075 APFloat LHSFloat = LHSElt.
getFloat();
3083 ResultElements.emplace_back(LHSFloat);
3087 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3095 unsigned TruncatedElements) {
3096 SubobjectDesignator &D = Result.Designator;
3099 if (TruncatedElements == D.Entries.size())
3101 assert(TruncatedElements >= D.MostDerivedPathLength &&
3102 "not casting to a derived class");
3108 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3112 if (isVirtualBaseClass(D.Entries[I]))
3118 D.Entries.resize(TruncatedElements);
3128 RL = &Info.Ctx.getASTRecordLayout(Derived);
3131 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3132 Obj.addDecl(Info, E,
Base,
false);
3141 if (!
Base->isVirtual())
3144 SubobjectDesignator &D = Obj.Designator;
3149 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
3155 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3157 Obj.addDecl(Info, E, BaseDecl,
true);
3165 PathI != PathE; ++PathI) {
3169 Type = (*PathI)->getType();
3181 llvm_unreachable(
"Class must be derived from the passed in base class!");
3196 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3200 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3201 LVal.addDecl(Info, E, FD);
3209 for (
const auto *
C : IFD->
chain())
3242 if (SOT == SizeOfType::SizeOf)
3243 Size = Info.Ctx.getTypeSizeInChars(
Type);
3245 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3262 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3268 int64_t Adjustment) {
3270 APSInt::get(Adjustment));
3285 LVal.Offset += SizeOfComponent;
3287 LVal.addComplex(Info, E, EltTy, Imag);
3301 const VarDecl *VD, CallStackFrame *Frame,
3302 unsigned Version,
APValue *&Result) {
3307 Result = Frame->getTemporary(VD, Version);
3311 if (!isa<ParmVarDecl>(VD)) {
3318 "missing value for local variable");
3319 if (Info.checkingPotentialConstantExpression())
3324 diag::note_unimplemented_constexpr_lambda_feature_ast)
3325 <<
"captures not currently allowed";
3332 if (Info.EvaluatingDecl ==
Base) {
3333 Result = Info.EvaluatingDeclValue;
3337 if (isa<ParmVarDecl>(VD)) {
3340 if (!Info.checkingPotentialConstantExpression() ||
3341 !Info.CurrentCall->Callee ||
3343 if (Info.getLangOpts().CPlusPlus11) {
3344 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3364 if (!Info.checkingPotentialConstantExpression()) {
3365 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3372 if (
Init->isValueDependent()) {
3379 if (!Info.checkingPotentialConstantExpression()) {
3380 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3381 ? diag::note_constexpr_ltor_non_constexpr
3382 : diag::note_constexpr_ltor_non_integral, 1)
3392 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3408 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3410 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3417 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3433 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3434 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3438 llvm_unreachable(
"base class missing from derived class's bases list");
3444 assert(!isa<SourceLocExpr>(Lit) &&
3445 "SourceLocExpr should have already been converted to a StringLiteral");
3448 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3450 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3451 assert(Index <= Str.size() &&
"Index too large");
3452 return APSInt::getUnsigned(Str.c_str()[Index]);
3455 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3456 Lit = PE->getFunctionName();
3459 Info.Ctx.getAsConstantArrayType(S->getType());
3460 assert(CAT &&
"string literal isn't an array");
3462 assert(CharType->
isIntegerType() &&
"unexpected character type");
3465 if (Index < S->getLength())
3466 Value = S->getCodeUnit(Index);
3478 AllocType.isNull() ? S->getType() : AllocType);
3479 assert(CAT &&
"string literal isn't an array");
3481 assert(CharType->
isIntegerType() &&
"unexpected character type");
3485 std::min(S->getLength(), Elts), Elts);
3488 if (Result.hasArrayFiller())
3490 for (
unsigned I = 0, N = Result.getArrayInitializedElts(); I != N; ++I) {
3491 Value = S->getCodeUnit(I);
3498 unsigned Size = Array.getArraySize();
3499 assert(Index < Size);
3502 unsigned OldElts = Array.getArrayInitializedElts();
3503 unsigned NewElts = std::max(Index+1, OldElts * 2);
3504 NewElts = std::min(Size, std::max(NewElts, 8u));
3508 for (
unsigned I = 0; I != OldElts; ++I)
3510 for (
unsigned I = OldElts; I != NewElts; ++I)
3514 Array.swap(NewValue);
3535 for (
auto *Field : RD->
fields())
3536 if (!Field->isUnnamedBitField() &&
3540 for (
auto &BaseSpec : RD->
bases())
3558 for (
auto *Field : RD->
fields()) {
3563 if (Field->isMutable() &&
3565 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3566 Info.Note(Field->getLocation(), diag::note_declared_at);
3574 for (
auto &BaseSpec : RD->
bases())
3584 bool MutableSubobject =
false) {
3589 switch (Info.IsEvaluatingDecl) {
3590 case EvalInfo::EvaluatingDeclKind::None:
3593 case EvalInfo::EvaluatingDeclKind::Ctor:
3595 if (Info.EvaluatingDecl ==
Base)
3600 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3601 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3602 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3605 case EvalInfo::EvaluatingDeclKind::Dtor:
3610 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3619 llvm_unreachable(
"unknown evaluating decl kind");
3624 return Info.CheckArraySize(
3633struct CompleteObject {
3641 CompleteObject() :
Value(nullptr) {}
3645 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3656 if (!Info.getLangOpts().CPlusPlus14)
3661 explicit operator bool()
const {
return !
Type.isNull(); }
3666 bool IsMutable =
false) {
3680template<
typename Sub
objectHandler>
3681typename SubobjectHandler::result_type
3683 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
3686 return handler.failed();
3687 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3688 if (Info.getLangOpts().CPlusPlus11)
3689 Info.FFDiag(E, Sub.isOnePastTheEnd()
3690 ? diag::note_constexpr_access_past_end
3691 : diag::note_constexpr_access_unsized_array)
3692 << handler.AccessKind;
3695 return handler.failed();
3701 const FieldDecl *VolatileField =
nullptr;
3704 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3709 if (!Info.checkingPotentialConstantExpression())
3710 Info.FFDiag(E, diag::note_constexpr_access_uninit)
3713 return handler.failed();
3721 Info.isEvaluatingCtorDtor(
3724 ConstructionPhase::None) {
3734 if (Info.getLangOpts().CPlusPlus) {
3738 if (VolatileField) {
3741 Decl = VolatileField;
3742 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3744 Loc = VD->getLocation();
3748 if (
auto *E = Obj.Base.dyn_cast<
const Expr *>())
3751 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3752 << handler.AccessKind << DiagKind <<
Decl;
3753 Info.Note(
Loc, diag::note_constexpr_volatile_here) << DiagKind;
3755 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3757 return handler.failed();
3765 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3767 return handler.failed();
3771 if (!handler.found(*O, ObjType))
3783 LastField =
nullptr;
3787 assert(CAT &&
"vla in literal type?");
3788 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3789 if (CAT->
getSize().ule(Index)) {
3792 if (Info.getLangOpts().CPlusPlus11)
3793 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3794 << handler.AccessKind;
3797 return handler.failed();
3804 else if (!
isRead(handler.AccessKind)) {
3806 return handler.failed();
3814 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3816 if (Info.getLangOpts().CPlusPlus11)
3817 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3818 << handler.AccessKind;
3821 return handler.failed();
3827 assert(I == N - 1 &&
"extracting subobject of scalar?");
3836 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3837 if (Field->isMutable() &&
3838 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
3839 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
3840 << handler.AccessKind << Field;
3841 Info.Note(Field->getLocation(), diag::note_declared_at);
3842 return handler.failed();
3851 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
3859 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
3860 << handler.AccessKind << Field << !UnionField << UnionField;
3861 return handler.failed();
3870 if (Field->getType().isVolatileQualified())
3871 VolatileField = Field;
3884struct ExtractSubobjectHandler {
3890 typedef bool result_type;
3891 bool failed() {
return false; }
3911 const CompleteObject &Obj,
3912 const SubobjectDesignator &Sub,
APValue &Result,
3915 ExtractSubobjectHandler Handler = {Info, E, Result, AK};
3920struct ModifySubobjectHandler {
3925 typedef bool result_type;
3931 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3937 bool failed() {
return false; }
3939 if (!checkConst(SubobjType))
3942 Subobj.
swap(NewVal);
3946 if (!checkConst(SubobjType))
3948 if (!NewVal.
isInt()) {
3957 if (!checkConst(SubobjType))
3965const AccessKinds ModifySubobjectHandler::AccessKind;
3969 const CompleteObject &Obj,
3970 const SubobjectDesignator &Sub,
3972 ModifySubobjectHandler Handler = { Info, NewVal, E };
3979 const SubobjectDesignator &A,
3980 const SubobjectDesignator &B,
3981 bool &WasArrayIndex) {
3982 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
3983 for (; I != N; ++I) {
3987 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
3988 WasArrayIndex =
true;
3996 if (A.Entries[I].getAsBaseOrMember() !=
3997 B.Entries[I].getAsBaseOrMember()) {
3998 WasArrayIndex =
false;
4001 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4003 ObjType = FD->getType();
4009 WasArrayIndex =
false;
4016 const SubobjectDesignator &A,
4017 const SubobjectDesignator &B) {
4018 if (A.Entries.size() != B.Entries.size())
4021 bool IsArray = A.MostDerivedIsArrayElement;
4022 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4031 return CommonLength >= A.Entries.size() - IsArray;
4038 if (LVal.InvalidBase) {
4040 return CompleteObject();
4044 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4045 return CompleteObject();
4048 CallStackFrame *Frame =
nullptr;
4050 if (LVal.getLValueCallIndex()) {
4051 std::tie(Frame, Depth) =
4052 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4054 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
4055 << AK << LVal.Base.is<
const ValueDecl*>();
4057 return CompleteObject();
4068 if (Info.getLangOpts().CPlusPlus)
4069 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4073 return CompleteObject();
4078 QualType BaseType = getType(LVal.Base);
4080 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4084 BaseVal = Info.EvaluatingDeclValue;
4087 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4090 Info.FFDiag(E, diag::note_constexpr_modify_global);
4091 return CompleteObject();
4095 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4097 return CompleteObject();
4099 return CompleteObject(LVal.Base, &
V, GD->getType());
4103 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4105 Info.FFDiag(E, diag::note_constexpr_modify_global);
4106 return CompleteObject();
4108 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4113 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4115 Info.FFDiag(E, diag::note_constexpr_modify_global);
4116 return CompleteObject();
4118 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4129 const VarDecl *VD = dyn_cast<VarDecl>(D);
4136 return CompleteObject();
4139 bool IsConstant = BaseType.
isConstant(Info.Ctx);
4140 bool ConstexprVar =
false;
4141 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4142 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
4148 if (IsAccess && isa<ParmVarDecl>(VD)) {
4152 }
else if (Info.getLangOpts().CPlusPlus14 &&
4159 Info.FFDiag(E, diag::note_constexpr_modify_global);
4160 return CompleteObject();
4163 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4165 return CompleteObject();
4169 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4170 if (Info.getLangOpts().CPlusPlus) {
4171 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4172 Info.Note(VD->
getLocation(), diag::note_declared_at);
4176 return CompleteObject();
4178 }
else if (!IsAccess) {
4179 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4180 }
else if (IsConstant && Info.checkingPotentialConstantExpression() &&
4183 }
else if (IsConstant) {
4187 if (Info.getLangOpts().CPlusPlus) {
4188 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4189 ? diag::note_constexpr_ltor_non_constexpr
4190 : diag::note_constexpr_ltor_non_integral, 1)
4192 Info.Note(VD->
getLocation(), diag::note_declared_at);
4198 if (Info.getLangOpts().CPlusPlus) {
4199 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4200 ? diag::note_constexpr_ltor_non_constexpr
4201 : diag::note_constexpr_ltor_non_integral, 1)
4203 Info.Note(VD->
getLocation(), diag::note_declared_at);
4207 return CompleteObject();
4212 return CompleteObject();
4214 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4216 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4217 return CompleteObject();
4219 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4220 LVal.Base.getDynamicAllocType());
4226 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4227 assert(MTE->getStorageDuration() ==
SD_Static &&
4228 "should have a frame for a non-global materialized temporary");
4255 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4258 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4259 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4260 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4261 return CompleteObject();
4264 BaseVal = MTE->getOrCreateValue(
false);
4265 assert(BaseVal &&
"got reference to unevaluated temporary");
4268 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4271 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4274 Info.Ctx.getLValueReferenceType(LValType));
4276 return CompleteObject();
4279 BaseVal = Frame->getTemporary(
Base, LVal.Base.getVersion());
4280 assert(BaseVal &&
"missing value for temporary");
4291 unsigned VisibleDepth = Depth;
4292 if (llvm::isa_and_nonnull<ParmVarDecl>(
4293 LVal.Base.dyn_cast<
const ValueDecl *>()))
4295 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4296 Info.EvalStatus.HasSideEffects) ||
4297 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4298 return CompleteObject();
4300 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4319 const LValue &LVal,
APValue &RVal,
4320 bool WantObjectRepresentation =
false) {
4321 if (LVal.Designator.Invalid)
4330 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4335 if (
Type.isVolatileQualified()) {
4341 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
4361 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4366 CompleteObject LitObj(LVal.Base, &Lit,
Base->getType());
4368 }
else if (isa<StringLiteral>(
Base) || isa<PredefinedExpr>(
Base)) {
4371 assert(LVal.Designator.Entries.size() <= 1 &&
4372 "Can only read characters from string literals");
4373 if (LVal.Designator.Entries.empty()) {
4380 if (LVal.Designator.isOnePastTheEnd()) {
4381 if (Info.getLangOpts().CPlusPlus11)
4382 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4387 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4394 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4400 if (LVal.Designator.Invalid)
4403 if (!Info.getLangOpts().CPlusPlus14) {
4413struct CompoundAssignSubobjectHandler {
4422 typedef bool result_type;
4427 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4433 bool failed() {
return false; }
4437 return found(Subobj.
getInt(), SubobjType);
4439 return found(Subobj.
getFloat(), SubobjType);
4446 return foundPointer(Subobj, SubobjType);
4448 return foundVector(Subobj, SubobjType);
4450 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4462 if (!checkConst(SubobjType))
4473 if (!checkConst(SubobjType))
4492 Info.Ctx.getLangOpts());
4495 PromotedLHSType, FValue) &&
4505 return checkConst(SubobjType) &&
4512 if (!checkConst(SubobjType))
4520 (Opcode != BO_Add && Opcode != BO_Sub)) {
4526 if (Opcode == BO_Sub)
4530 LVal.setFrom(Info.Ctx, Subobj);
4533 LVal.moveInto(Subobj);
4539const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
4544 const LValue &LVal,
QualType LValType,
4548 if (LVal.Designator.Invalid)
4551 if (!Info.getLangOpts().CPlusPlus14) {
4557 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
4559 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4563struct IncDecSubobjectHandler {
4569 typedef bool result_type;
4574 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4580 bool failed() {
return false; }
4591 return found(Subobj.
getInt(), SubobjType);
4593 return found(Subobj.
getFloat(), SubobjType);
4603 return foundPointer(Subobj, SubobjType);
4611 if (!checkConst(SubobjType))
4633 bool WasNegative =
Value.isNegative();
4645 unsigned BitWidth =
Value.getBitWidth();
4646 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
4647 ActualValue.setBit(BitWidth);
4654 if (!checkConst(SubobjType))
4661 APFloat::opStatus St;
4663 St =
Value.add(One, RM);
4665 St =
Value.subtract(One, RM);
4669 if (!checkConst(SubobjType))
4681 LVal.setFrom(Info.Ctx, Subobj);
4685 LVal.moveInto(Subobj);
4694 if (LVal.Designator.Invalid)
4697 if (!Info.getLangOpts().CPlusPlus14) {
4704 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(E), AK, Old};
4705 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4711 if (Object->getType()->isPointerType() && Object->isPRValue())
4714 if (Object->isGLValue())
4717 if (Object->getType()->isLiteralType(Info.Ctx))
4720 if (Object->getType()->isRecordType() && Object->isPRValue())
4723 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType();
4742 bool IncludeMember =
true) {
4749 if (!MemPtr.getDecl()) {
4755 if (MemPtr.isDerivedMember()) {
4759 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
4760 LV.Designator.Entries.size()) {
4764 unsigned PathLengthToMember =
4765 LV.Designator.Entries.size() - MemPtr.Path.size();
4766 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
4768 LV.Designator.Entries[PathLengthToMember + I]);
4778 PathLengthToMember))
4780 }
else if (!MemPtr.Path.empty()) {
4782 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
4783 MemPtr.Path.size() + IncludeMember);
4789 assert(RD &&
"member pointer access on non-class-type expression");
4791 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
4799 MemPtr.getContainingRecord()))
4804 if (IncludeMember) {
4805 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
4809 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
4813 llvm_unreachable(
"can't construct reference to bound member function");
4817 return MemPtr.getDecl();
4823 bool IncludeMember =
true) {
4827 if (Info.noteFailure()) {
4835 BO->
getRHS(), IncludeMember);
4842 SubobjectDesignator &D = Result.Designator;
4843 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
4851 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
4852 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4853 << D.MostDerivedType << TargetQT;
4859 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
4862 if (NewEntriesSize == D.MostDerivedPathLength)
4863 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
4865 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
4867 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4868 << D.MostDerivedType << TargetQT;
4882 if (!Result.isAbsent())
4886 if (RD->isInvalidDecl()) {
4890 if (RD->isUnion()) {
4895 std::distance(RD->field_begin(), RD->field_end()));
4899 End = RD->bases_end();
4900 I != End; ++I, ++Index)
4904 for (
const auto *I : RD->fields()) {
4905 if (I->isUnnamedBitField())
4908 I->getType(), Result.getStructField(I->getFieldIndex()));
4916 if (Result.hasArrayFiller())
4928enum EvalStmtResult {
4952 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
4953 ScopeKind::Block, Result);
4958 return Info.noteSideEffect();
4977 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
4981 for (
auto *BD : DD->bindings())
4982 if (
auto *VD = BD->getHoldingVar())
4990 if (Info.noteSideEffect())
4992 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
4993 "reach invalid code path.");
4999 const Expr *Cond,
bool &Result) {
5002 FullExpressionRAII
Scope(Info);
5007 return Scope.destroy();
5020struct TempVersionRAII {
5021 CallStackFrame &Frame;
5023 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5024 Frame.pushTempVersion();
5027 ~TempVersionRAII() {
5028 Frame.popTempVersion();
5042 BlockScopeRAII
Scope(Info);
5044 EvalStmtResult ESR =
EvaluateStmt(Result, Info, Body, Case);
5045 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5050 return ESR_Succeeded;
5053 return ESR_Continue;
5056 case ESR_CaseNotFound:
5059 llvm_unreachable(
"Invalid EvalStmtResult!");
5065 BlockScopeRAII
Scope(Info);
5072 if (ESR != ESR_Succeeded) {
5073 if (ESR != ESR_Failed && !
Scope.destroy())
5079 FullExpressionRAII CondScope(Info);
5091 if (!CondScope.destroy())
5100 if (isa<DefaultStmt>(SC)) {
5105 const CaseStmt *CS = cast<CaseStmt>(SC);
5116 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5120 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5125 return ESR_Succeeded;
5131 case ESR_CaseNotFound:
5135 diag::note_constexpr_stmt_expr_unsupported);
5138 llvm_unreachable(
"Invalid EvalStmtResult!");
5148 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5158 if (!Info.nextStep(S))
5164 switch (S->getStmtClass()) {
5165 case Stmt::CompoundStmtClass:
5169 case Stmt::LabelStmtClass:
5170 case Stmt::AttributedStmtClass:
5171 case Stmt::DoStmtClass:
5174 case Stmt::CaseStmtClass:
5175 case Stmt::DefaultStmtClass:
5180 case Stmt::IfStmtClass: {
5183 const IfStmt *IS = cast<IfStmt>(S);
5187 BlockScopeRAII
Scope(Info);
5193 if (ESR != ESR_CaseNotFound) {
5194 assert(ESR != ESR_Succeeded);
5205 if (ESR == ESR_Failed)
5207 if (ESR != ESR_CaseNotFound)
5208 return Scope.destroy() ? ESR : ESR_Failed;
5210 return ESR_CaseNotFound;
5213 if (ESR == ESR_Failed)
5215 if (ESR != ESR_CaseNotFound)
5216 return Scope.destroy() ? ESR : ESR_Failed;
5217 return ESR_CaseNotFound;
5220 case Stmt::WhileStmtClass: {
5221 EvalStmtResult ESR =
5223 if (ESR != ESR_Continue)
5228 case Stmt::ForStmtClass: {
5229 const ForStmt *FS = cast<ForStmt>(S);
5230 BlockScopeRAII
Scope(Info);
5234 if (
const Stmt *
Init = FS->getInit()) {
5236 if (ESR != ESR_CaseNotFound) {
5237 assert(ESR != ESR_Succeeded);
5242 EvalStmtResult ESR =
5244 if (ESR != ESR_Continue)
5246 if (
const auto *Inc = FS->getInc()) {
5247 if (Inc->isValueDependent()) {
5251 FullExpressionRAII IncScope(Info);
5259 case Stmt::DeclStmtClass: {
5262 const DeclStmt *DS = cast<DeclStmt>(S);
5263 for (
const auto *D : DS->
decls()) {
5264 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5267 if (VD->hasLocalStorage() && !VD->getInit())
5275 return ESR_CaseNotFound;
5279 return ESR_CaseNotFound;
5283 switch (S->getStmtClass()) {
5285 if (
const Expr *E = dyn_cast<Expr>(S)) {
5294 FullExpressionRAII
Scope(Info);
5298 return ESR_Succeeded;
5301 Info.FFDiag(S->getBeginLoc()) << S->getSourceRange();
5304 case Stmt::NullStmtClass:
5305 return ESR_Succeeded;
5307 case Stmt::DeclStmtClass: {
5308 const DeclStmt *DS = cast<DeclStmt>(S);
5309 for (
const auto *D : DS->
decls()) {
5310 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5314 FullExpressionRAII
Scope(Info);
5317 if (!
Scope.destroy())
5320 return ESR_Succeeded;
5323 case Stmt::ReturnStmtClass: {
5324 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
5325 FullExpressionRAII
Scope(Info);
5334 :
Evaluate(Result.Value, Info, RetExpr)))
5336 return Scope.destroy() ? ESR_Returned : ESR_Failed;
5339 case Stmt::CompoundStmtClass: {
5340 BlockScopeRAII
Scope(Info);
5343 for (
const auto *BI : CS->
body()) {
5344 EvalStmtResult ESR =
EvaluateStmt(Result, Info, BI, Case);
5345 if (ESR == ESR_Succeeded)
5347 else if (ESR != ESR_CaseNotFound) {
5348 if (ESR != ESR_Failed && !
Scope.destroy())
5354 return ESR_CaseNotFound;
5355 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5358 case Stmt::IfStmtClass: {
5359 const IfStmt *IS = cast<IfStmt>(S);
5362 BlockScopeRAII
Scope(Info);
5365 if (ESR != ESR_Succeeded) {
5366 if (ESR != ESR_Failed && !
Scope.destroy())
5376 if (!Info.InConstantContext)
5383 EvalStmtResult ESR =
EvaluateStmt(Result, Info, SubStmt);
5384 if (ESR != ESR_Succeeded) {
5385 if (ESR != ESR_Failed && !
Scope.destroy())
5390 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5393 case Stmt::WhileStmtClass: {
5394 const WhileStmt *WS = cast<WhileStmt>(S);
5396 BlockScopeRAII
Scope(Info);
5405 if (ESR != ESR_Continue) {
5406 if (ESR != ESR_Failed && !
Scope.destroy())
5410 if (!
Scope.destroy())
5413 return ESR_Succeeded;
5416 case Stmt::DoStmtClass: {
5417 const DoStmt *DS = cast<DoStmt>(S);
5421 if (ESR != ESR_Continue)
5430 FullExpressionRAII CondScope(Info);
5432 !CondScope.destroy())
5435 return ESR_Succeeded;
5438 case Stmt::ForStmtClass: {
5439 const ForStmt *FS = cast<ForStmt>(S);
5440 BlockScopeRAII ForScope(Info);
5441 if (FS->getInit()) {
5442 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5443 if (ESR != ESR_Succeeded) {
5444 if (ESR != ESR_Failed && !ForScope.destroy())
5450 BlockScopeRAII IterScope(Info);
5451 bool Continue =
true;
5452 if (FS->getCond() && !
EvaluateCond(Info, FS->getConditionVariable(),
5453 FS->getCond(), Continue))
5459 if (ESR != ESR_Continue) {
5460 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
5465 if (
const auto *Inc = FS->getInc()) {
5466 if (Inc->isValueDependent()) {
5470 FullExpressionRAII IncScope(Info);
5476 if (!IterScope.destroy())
5479 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
5482 case Stmt::CXXForRangeStmtClass: {
5484 BlockScopeRAII
Scope(Info);
5487 if (FS->getInit()) {
5488 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getInit());
5489 if (ESR != ESR_Succeeded) {
5490 if (ESR != ESR_Failed && !
Scope.destroy())
5497 EvalStmtResult ESR =
EvaluateStmt(Result, Info, FS->getRangeStmt());
5498 if (ESR != ESR_Succeeded) {
5499 if (ESR != ESR_Failed && !
Scope.destroy())
5506 if (!FS->getBeginStmt() || !FS->getEndStmt() || !FS->getCond())
5511 if (ESR != ESR_Succeeded) {
5512 if (ESR != ESR_Failed && !
Scope.destroy())
5517 if (ESR != ESR_Succeeded) {
5518 if (ESR != ESR_Failed && !
Scope.destroy())
5526 if (FS->getCond()->isValueDependent()) {
5531 bool Continue =
true;
5532 FullExpressionRAII CondExpr(Info);
5540 BlockScopeRAII InnerScope(Info);
5541 ESR =
EvaluateStmt(Result, Info, FS->getLoopVarStmt());
5542 if (ESR != ESR_Succeeded) {
5543 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5550 if (ESR != ESR_Continue) {
5551 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
5555 if (FS->getInc()->isValueDependent()) {
5564 if (!InnerScope.destroy())
5568 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5571 case Stmt::SwitchStmtClass:
5574 case Stmt::ContinueStmtClass:
5575 return ESR_Continue;
5577 case Stmt::BreakStmtClass:
5580 case Stmt::LabelStmtClass:
5581 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
5583 case Stmt::AttributedStmtClass: {
5584 const auto *AS = cast<AttributedStmt>(S);
5585 const auto *SS = AS->getSubStmt();
5586 MSConstexprContextRAII ConstexprContext(
5587 *Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
5588 isa<ReturnStmt>(SS));
5590 auto LO = Info.getCtx().getLangOpts();
5591 if (LO.CXXAssumptions && !LO.MSVCCompat) {
5592 for (
auto *
Attr : AS->getAttrs()) {
5593 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
5597 auto *Assumption = AA->getAssumption();
5598 if (Assumption->isValueDependent())
5601 if (Assumption->HasSideEffects(Info.getCtx()))
5608 Info.CCEDiag(Assumption->getExprLoc(),
5609 diag::note_constexpr_assumption_failed);
5618 case Stmt::CaseStmtClass:
5619 case Stmt::DefaultStmtClass:
5620 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
5621 case Stmt::CXXTryStmtClass:
5623 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
5633 bool IsValueInitialization) {
5640 if (!CD->
isConstexpr() && !IsValueInitialization) {
5641 if (Info.getLangOpts().CPlusPlus11) {
5644 Info.CCEDiag(
Loc, diag::note_constexpr_invalid_function, 1)
5646 Info.Note(CD->
getLocation(), diag::note_declared_at);
5648 Info.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
5662 if (Info.checkingPotentialConstantExpression() && !
Definition &&
5670 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5677 if (!Info.Ctx.getLangOpts().CPlusPlus20 && isa<CXXMethodDecl>(
Declaration) &&
5679 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
5682 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5688 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
5692 if (Info.getLangOpts().CPlusPlus11) {
5697 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
5698 if (CD && CD->isInheritingConstructor()) {
5699 auto *Inherited = CD->getInheritedConstructor().getConstructor();
5700 if (!Inherited->isConstexpr())
5701 DiagDecl = CD = Inherited;
5707 if (CD && CD->isInheritingConstructor())
5708 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
5709 << CD->getInheritedConstructor().getConstructor()->
getParent();
5711 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
5713 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
5715 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
5721struct CheckDynamicTypeHandler {
5723 typedef bool result_type;
5724 bool failed() {
return false; }
5727 bool found(APFloat &
Value,
QualType SubobjType) {
return true; }
5735 if (This.Designator.Invalid)
5747 if (This.Designator.isOnePastTheEnd() ||
5748 This.Designator.isMostDerivedAnUnsizedArray()) {
5749 Info.FFDiag(E, This.Designator.isOnePastTheEnd()
5750 ? diag::note_constexpr_access_past_end
5751 : diag::note_constexpr_access_unsized_array)
5754 }
else if (Polymorphic) {
5760 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
5761 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
5768 CheckDynamicTypeHandler Handler{AK};
5769 return Obj &&
findSubobject(Info, E, Obj, This.Designator, Handler);
5791 unsigned PathLength) {
5792 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
5793 Designator.Entries.size() &&
"invalid path length");
5794 return (PathLength ==
Designator.MostDerivedPathLength)
5795 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
5796 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
5808 return std::nullopt;
5817 This.Designator.MostDerivedType->getAsCXXRecordDecl();
5820 return std::nullopt;
5828 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
5829 PathLength <= Path.size(); ++PathLength) {
5830 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
5831 Path.slice(0, PathLength))) {
5832 case ConstructionPhase::Bases:
5833 case ConstructionPhase::DestroyingBases:
5838 case ConstructionPhase::None:
5839 case ConstructionPhase::AfterBases:
5840 case ConstructionPhase::AfterFields:
5841 case ConstructionPhase::Destroying:
5853 return std::nullopt;
5871 unsigned PathLength = DynType->PathLength;
5872 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
5885 if (Callee->isPureVirtual()) {
5886 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
5887 Info.Note(Callee->getLocation(), diag::note_declared_at);
5893 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
5895 CovariantAdjustmentPath.push_back(Callee->getReturnType());
5896 for (
unsigned CovariantPathLength = PathLength + 1;
5897 CovariantPathLength != This.Designator.Entries.size();
5898 ++CovariantPathLength) {
5903 if (Next && !Info.Ctx.hasSameUnqualifiedType(
5904 Next->getReturnType(), CovariantAdjustmentPath.back()))
5905 CovariantAdjustmentPath.push_back(Next->getReturnType());
5907 if (!Info.Ctx.hasSameUnqualifiedType(Found->
getReturnType(),
5908 CovariantAdjustmentPath.back()))
5925 assert(Result.isLValue() &&
5926 "unexpected kind of APValue for covariant return");
5927 if (Result.isNullPointer())
5931 LVal.setFrom(Info.Ctx, Result);
5933 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
5934 for (
unsigned I = 1; I != Path.size(); ++I) {
5935 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
5936 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
5937 if (OldClass != NewClass &&
5940 OldClass = NewClass;
5943 LVal.moveInto(Result);
5952 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
5954 return BaseSpec.getAccessSpecifier() ==
AS_public;
5956 llvm_unreachable(
"Base is not a direct base of Derived");
5966 SubobjectDesignator &D = Ptr.Designator;
5972 if (Ptr.isNullPointer() && !E->
isGLValue())
5978 std::optional<DynamicType> DynType =
5990 assert(
C &&
"dynamic_cast target is not void pointer nor class");
5991 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(
C));
5998 Ptr.setNull(Info.Ctx, E->
getType());
6005 DynType->Type->isDerivedFrom(
C)))
6007 else if (!Paths || Paths->begin() == Paths->end())
6009 else if (Paths->isAmbiguous(CQT))
6012 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6015 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6016 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6017 << Info.Ctx.getRecordType(DynType->Type)
6025 for (
int PathLength = Ptr.Designator.Entries.size();
6026 PathLength >= (
int)DynType->PathLength; --PathLength) {
6031 if (PathLength > (
int)DynType->PathLength &&
6034 return RuntimeCheckFailed(
nullptr);
6041 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.isAmbiguous(CQT) &&
6054 return RuntimeCheckFailed(&Paths);
6058struct StartLifetimeOfUnionMemberHandler {
6060 const Expr *LHSExpr;
6063 bool Failed =
false;
6066 typedef bool result_type;
6067 bool failed() {
return Failed; }
6083 }
else if (DuringInit) {
6087 Info.FFDiag(LHSExpr,
6088 diag::note_constexpr_union_member_change_during_init);
6097 llvm_unreachable(
"wrong value kind for union object");
6100 llvm_unreachable(
"wrong value kind for union object");
6105const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6112 const Expr *LHSExpr,
6113 const LValue &LHS) {
6114 if (LHS.InvalidBase || LHS.Designator.Invalid)
6120 unsigned PathLength = LHS.Designator.Entries.size();
6121 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6123 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6124 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6127 if (!FD || FD->getType()->isReferenceType())
6131 if (FD->getParent()->isUnion()) {
6136 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6137 if (!RD || RD->hasTrivialDefaultConstructor())
6138 UnionPathLengths.push_back({PathLength - 1, FD});
6144 LHS.Designator.Entries[PathLength]
6145 .getAsBaseOrMember().getPointer()));
6149 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6151 auto *
Base = ASE->getBase()->IgnoreImplicit();
6152 if (!
Base->getType()->isArrayType())
6158 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6161 if (ICE->getCastKind() == CK_NoOp)
6163 if (ICE->getCastKind() != CK_DerivedToBase &&
6164 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6168 if (Elt->isVirtual()) {
6177 LHS.Designator.Entries[PathLength]
6178 .getAsBaseOrMember().getPointer()));
6188 if (UnionPathLengths.empty())
6193 CompleteObject Obj =
6197 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6198 llvm::reverse(UnionPathLengths)) {
6200 SubobjectDesignator D = LHS.Designator;
6201 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6203 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6204 ConstructionPhase::AfterBases;
6205 StartLifetimeOfUnionMemberHandler StartLifetime{
6206 Info, LHSExpr, LengthAndField.second, DuringInit};
6215 CallRef
Call, EvalInfo &Info,
6223 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6224 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6225 ScopeKind::Call, LV);
6231 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6232 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6242 bool RightToLeft =
false) {
6244 llvm::SmallBitVector ForbiddenNullArgs;
6245 if (Callee->hasAttr<NonNullAttr>()) {
6246 ForbiddenNullArgs.resize(Args.size());
6247 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6248 if (!
Attr->args_size()) {
6249 ForbiddenNullArgs.set();
6252 for (
auto Idx :
Attr->args()) {
6253 unsigned ASTIdx = Idx.getASTIndex();
6254 if (ASTIdx >= Args.size())
6256 ForbiddenNullArgs[ASTIdx] =
true;
6260 for (
unsigned I = 0; I < Args.size(); I++) {
6261 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
6263 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
6264 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
6268 if (!Info.noteFailure())
6280 bool CopyObjectRepresentation) {
6282 CallStackFrame *Frame = Info.CurrentCall;
6283 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
6291 RefLValue.setFrom(Info.Ctx, *RefValue);
6294 CopyObjectRepresentation);
6301 CallRef
Call,
const Stmt *Body, EvalInfo &Info,
6302 APValue &Result,
const LValue *ResultSlot) {
6303 if (!Info.CheckCallLimit(CallLoc))
6328 This->moveInto(Result);
6337 if (!Info.checkingPotentialConstantExpression())
6339 Frame.LambdaThisCaptureField);
6344 if (ESR == ESR_Succeeded) {
6345 if (Callee->getReturnType()->isVoidType())
6347 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
6349 return ESR == ESR_Returned;
6356 EvalInfo &Info,
APValue &Result) {
6358 if (!Info.CheckCallLimit(CallLoc))
6363 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
6367 EvalInfo::EvaluatingConstructorRAII EvalObj(
6369 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
6381 if ((*I)->getInit()->isValueDependent()) {
6385 FullExpressionRAII InitScope(Info);
6387 !InitScope.destroy())
6410 if (!Result.hasValue()) {
6423 BlockScopeRAII LifetimeExtendedScope(Info);
6426 unsigned BasesSeen = 0;
6436 assert(
Indirect &&
"fields out of order?");
6442 assert(FieldIt != RD->
field_end() &&
"missing field?");
6443 if (!FieldIt->isUnnamedBitField())
6446 Result.getStructField(FieldIt->getFieldIndex()));
6451 LValue Subobject = This;
6452 LValue SubobjectParent = This;
6457 if (I->isBaseInitializer()) {
6458 QualType BaseType(I->getBaseClass(), 0);
6462 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
6463 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
6464 "base class initializers not in expected order");
6470 Value = &Result.getStructBase(BasesSeen++);
6471 }
else if ((FD = I->getMember())) {
6476 Value = &Result.getUnionValue();
6478 SkipToField(FD,
false);
6484 auto IndirectFieldChain = IFD->chain();
6485 for (
auto *
C : IndirectFieldChain) {
6486 FD = cast<FieldDecl>(
C);
6494 (
Value->isUnion() &&
Value->getUnionField() != FD)) {
6506 if (
C == IndirectFieldChain.back())
6507 SubobjectParent = Subobject;
6513 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
6514 SkipToField(FD,
true);
6519 llvm_unreachable(
"unknown base initializer kind");
6526 if (
Init->isValueDependent()) {
6530 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
6531 isa<CXXDefaultInitExpr>(
Init));
6532 FullExpressionRAII InitScope(Info);
6538 if (!Info.noteFailure())
6546 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
6547 EvalObj.finishedConstructingBases();
6552 for (; FieldIt != RD->
field_end(); ++FieldIt) {
6553 if (!FieldIt->isUnnamedBitField())
6556 Result.getStructField(FieldIt->getFieldIndex()));
6560 EvalObj.finishedConstructingFields();
6564 LifetimeExtendedScope.destroy();
6570 EvalInfo &Info,
APValue &Result) {
6571 CallScopeRAII CallScope(Info);
6577 CallScope.destroy();
6589 This.moveInto(Printable);
6591 diag::note_constexpr_destroy_out_of_lifetime)
6592 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(
T));
6608 LValue ElemLV = This;
6609 ElemLV.addArray(Info, &LocE, CAT);
6616 if (Size && Size >
Value.getArrayInitializedElts())
6619 for (; Size != 0; --Size) {
6620 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
6633 if (
T.isDestructedType()) {
6635 diag::note_constexpr_unsupported_destruction)
6645 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
6670 if (!Info.CheckCallLimit(CallRange.
getBegin()))
6679 CallStackFrame Frame(Info, CallRange,
Definition, &This,
nullptr,
6684 EvalInfo::EvaluatingDestructorRAII EvalObj(
6686 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
6687 if (!EvalObj.DidInsert) {
6694 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
6714 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
6715 if (FD->isUnnamedBitField())
6718 LValue Subobject = This;
6722 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
6729 EvalObj.startedDestroyingBases();
6736 LValue Subobject = This;
6741 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
6746 assert(BasesLeft == 0 &&
"NumBases was wrong?");
6754struct DestroyObjectHandler {
6760 typedef bool result_type;
6761 bool failed() {
return false; }
6767 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
6771 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
6780 const LValue &This,
QualType ThisType) {
6782 DestroyObjectHandler Handler = {Info, E, This,
AK_Destroy};
6783 return Obj &&
findSubobject(Info, E, Obj, This.Designator, Handler);
6792 if (Info.EvalStatus.HasSideEffects)
6803 if (Info.checkingPotentialConstantExpression() ||
6804 Info.SpeculativeEvaluationDepth)
6808 auto Caller = Info.getStdAllocatorCaller(
"allocate");
6810 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
6811 ? diag::note_constexpr_new_untyped
6812 : diag::note_constexpr_new);
6816 QualType ElemType = Caller.ElemType;
6819 diag::note_constexpr_new_not_complete_object_type)
6827 bool IsNothrow =
false;
6828 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
6836 APInt Size, Remainder;
6837 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
6838 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
6839 if (Remainder != 0) {
6841 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
6842 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
6846 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
6847 Size.getZExtValue(), !IsNothrow)) {
6849 Result.setNull(Info.Ctx, E->
getType());
6855 QualType AllocType = Info.Ctx.getConstantArrayType(
6856 ElemType, Size,
nullptr, ArraySizeModifier::Normal, 0);
6857 APValue *Val = Info.createHeapAlloc(E, AllocType, Result);
6859 Result.addArray(Info, E, cast<ConstantArrayType>(AllocType));
6866 return DD->isVirtual();
6873 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
6884 DynAlloc::Kind DeallocKind) {
6885 auto PointerAsString = [&] {
6886 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
6891 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
6892 << PointerAsString();
6895 return std::nullopt;
6898 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
6900 Info.FFDiag(E, diag::note_constexpr_double_delete);
6901 return std::nullopt;
6904 if (DeallocKind != (*Alloc)->getKind()) {
6906 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
6907 << DeallocKind << (*Alloc)->getKind() << AllocType;
6909 return std::nullopt;
6912 bool Subobject =
false;
6913 if (DeallocKind == DynAlloc::New) {
6914 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
6915 Pointer.Designator.isOnePastTheEnd();
6917 Subobject =
Pointer.Designator.Entries.size() != 1 ||
6918 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
6921 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
6922 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
6923 return std::nullopt;
6931 if (Info.checkingPotentialConstantExpression() ||
6932 Info.SpeculativeEvaluationDepth)
6936 if (!Info.getStdAllocatorCaller(
"deallocate")) {
6944 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
6947 if (
Pointer.Designator.Invalid)
6952 if (
Pointer.isNullPointer()) {
6953 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
6969class BitCastBuffer {
6977 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
6978 "Need at least 8 bit unsigned char");
6980 bool TargetIsLittleEndian;
6983 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
6984 : Bytes(Width.getQuantity()),
6985 TargetIsLittleEndian(TargetIsLittleEndian) {}
6989 for (
CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
6992 if (!Bytes[I.getQuantity()])
6994 Output.push_back(*Bytes[I.getQuantity()]);
6996 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
6997 std::reverse(Output.begin(), Output.end());
7002 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7003 std::reverse(Input.begin(), Input.end());
7006 for (
unsigned char Byte : Input) {
7007 assert(!Bytes[Offset.getQuantity() + Index] &&
"overwriting a byte?");
7008 Bytes[Offset.getQuantity() + Index] = Byte;
7013 size_t size() {
return Bytes.size(); }
7018class APValueToBufferConverter {
7020 BitCastBuffer Buffer;
7023 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
7026 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7035 assert((
size_t)Offset.getQuantity() <= Buffer.size());
7048 return visitInt(Val.
getInt(), Ty, Offset);
7050 return visitFloat(Val.
getFloat(), Ty, Offset);
7052 return visitArray(Val, Ty, Offset);
7054 return visitRecord(Val, Ty, Offset);
7056 return visitVector(Val, Ty, Offset);
7067 diag::note_constexpr_bit_cast_unsupported_type)
7073 llvm_unreachable(
"LValue subobject in bit_cast?");
7075 llvm_unreachable(
"Unhandled APValue::ValueKind");
7083 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7084 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7095 unsigned FieldIdx = 0;
7097 if (FD->isBitField()) {
7099 diag::note_constexpr_bit_cast_unsupported_bitfield);
7105 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7106 "only bit-fields can have sub-char alignment");
7108 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7128 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7130 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7137 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7138 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7153 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7159 diag::note_constexpr_bit_cast_invalid_vector)
7161 << Info.Ctx.getCharWidth();
7165 if (EltTy->isRealFloatingType() && &Info.Ctx.getFloatTypeSemantics(EltTy) ==
7166 &APFloat::x87DoubleExtended()) {
7171 diag::note_constexpr_bit_cast_unsupported_type)
7185 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7187 llvm::APInt Res = llvm::APInt::getZero(NElts);
7188 for (
unsigned I = 0; I < NElts; ++I) {
7190 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7191 "bool vector element must be 1-bit unsigned integer!");
7193 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7197 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7198 Buffer.writeObject(Offset, Bytes);
7202 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7203 for (
unsigned I = 0; I < NElts; ++I) {
7204 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7213 APSInt AdjustedVal = Val;
7214 unsigned Width = AdjustedVal.getBitWidth();
7216 Width = Info.Ctx.getTypeSize(Ty);
7217 AdjustedVal = AdjustedVal.extend(Width);
7221 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7222 Buffer.writeObject(Offset, Bytes);
7227 APSInt AsInt(Val.bitcastToAPInt());
7228 return visitInt(AsInt, Ty, Offset);
7232 static std::optional<BitCastBuffer>
7235 APValueToBufferConverter Converter(Info, DstSize, BCE);
7237 return std::nullopt;
7238 return Converter.Buffer;
7243class BufferToAPValueConverter {
7245 const BitCastBuffer &Buffer;
7248 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
7250 : Info(Info), Buffer(Buffer), BCE(BCE) {}
7255 std::nullopt_t unsupportedType(
QualType Ty) {
7257 diag::note_constexpr_bit_cast_unsupported_type)
7259 return std::nullopt;
7262 std::nullopt_t unrepresentableValue(
QualType Ty,
const APSInt &Val) {
7264 diag::note_constexpr_bit_cast_unrepresentable_value)
7266 return std::nullopt;
7270 const EnumType *EnumSugar =
nullptr) {
7284 const llvm::fltSemantics &Semantics =
7285 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7286 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
7287 assert(NumBits % 8 == 0);
7294 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
7297 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
7301 if (!IsStdByte && !IsUChar) {
7302 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar :
T, 0);
7304 diag::note_constexpr_bit_cast_indet_dest)
7305 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
7306 return std::nullopt;
7312 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
7313 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
7318 unsigned IntWidth = Info.Ctx.getIntWidth(
QualType(
T, 0));
7319 if (IntWidth != Val.getBitWidth()) {
7320 APSInt Truncated = Val.trunc(IntWidth);
7321 if (Truncated.extend(Val.getBitWidth()) != Val)
7322 return unrepresentableValue(
QualType(
T, 0), Val);
7330 const llvm::fltSemantics &Semantics =
7331 Info.Ctx.getFloatTypeSemantics(
QualType(
T, 0));
7342 unsigned NumBases = 0;
7343 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
7344 NumBases = CXXRD->getNumBases();
7350 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7351 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7355 std::optional<APValue> SubObj = visitType(
7358 return std::nullopt;
7359 ResultVal.getStructBase(I) = *SubObj;
7364 unsigned FieldIdx = 0;
7368 if (FD->isBitField()) {
7370 diag::note_constexpr_bit_cast_unsupported_bitfield);
7371 return std::nullopt;
7375 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
7381 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
7383 return std::nullopt;
7384 ResultVal.getStructField(FieldIdx) = *SubObj;
7393 assert(!RepresentationType.
isNull() &&
7394 "enum forward decl should be caught by Sema");
7395 const auto *AsBuiltin =
7399 return visit(AsBuiltin, Offset, Ty);
7407 for (
size_t I = 0; I !=
Size; ++I) {
7408 std::optional<APValue> ElementValue =
7411 return std::nullopt;
7412 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
7424 if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) {
7430 diag::note_constexpr_bit_cast_invalid_vector)
7431 <<
QualType(VTy, 0) << EltSize << NElts << Info.Ctx.getCharWidth();
7432 return std::nullopt;
7436 &APFloat::x87DoubleExtended()) {
7441 diag::note_constexpr_bit_cast_unsupported_type)
7443 return std::nullopt;
7447 Elts.reserve(NElts);
7457 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7460 Bytes.reserve(NElts / 8);
7462 return std::nullopt;
7464 APSInt SValInt(NElts,
true);
7465 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
7467 for (
unsigned I = 0; I < NElts; ++I) {
7469 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
7476 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7477 for (
unsigned I = 0; I < NElts; ++I) {
7478 std::optional<APValue> EltValue =
7479 visitType(EltTy, Offset + I * EltSizeChars);
7481 return std::nullopt;
7482 Elts.push_back(std::move(*EltValue));
7486 return APValue(Elts.data(), Elts.size());
7489 std::optional<APValue> visit(
const Type *Ty,
CharUnits Offset) {
7490 return unsupportedType(
QualType(Ty, 0));
7497#define TYPE(Class, Base) \
7499 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
7500#define ABSTRACT_TYPE(Class, Base)
7501#define NON_CANONICAL_TYPE(Class, Base) \
7503 llvm_unreachable("non-canonical type should be impossible!");
7504#define DEPENDENT_TYPE(Class, Base) \
7507 "dependent types aren't supported in the constant evaluator!");
7508#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
7510 llvm_unreachable("either dependent or not canonical!");
7511#include "clang/AST/TypeNodes.inc"
7513 llvm_unreachable(
"Unhandled Type::TypeClass");
7518 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
7520 BufferToAPValueConverter Converter(Info, Buffer, BCE);
7528 bool CheckingDest) {
7531 auto diag = [&](
int Reason) {
7533 Info->FFDiag(
Loc, diag::note_constexpr_bit_cast_invalid_type)
7534 << CheckingDest << (Reason == 4) << Reason;
7539 Info->
Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
7540 << NoteTy << Construct << Ty;
7554 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
7556 if (!checkBitCastConstexprEligibilityType(
Loc, BS.
getType(), Info, Ctx,
7561 if (FD->getType()->isReferenceType())
7563 if (!checkBitCastConstexprEligibilityType(
Loc, FD->getType(), Info, Ctx,
7565 return note(0, FD->getType(), FD->getBeginLoc());
7571 Info, Ctx, CheckingDest))
7577static bool checkBitCastConstexprEligibility(EvalInfo *Info,
7580 bool DestOK = checkBitCastConstexprEligibilityType(
7582 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
7588static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7591 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7592 "no host or target supports non 8-bit chars");
7594 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
7598 std::optional<BitCastBuffer> Buffer =
7599 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
7604 std::optional<APValue> MaybeDestValue =
7605 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
7606 if (!MaybeDestValue)
7609 DestValue = std::move(*MaybeDestValue);
7613static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
7616 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
7617 "no host or target supports non 8-bit chars");
7619 "LValueToRValueBitcast requires an lvalue operand!");
7621 LValue SourceLValue;
7623 SourceLValue.setFrom(Info.Ctx, SourceValue);
7626 SourceRValue,
true))
7629 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
7632template <
class Derived>
7633class ExprEvaluatorBase
7636 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
7638 return getDerived().Success(
V, E);
7640 bool DerivedZeroInitialization(
const Expr *E) {
7641 return getDerived().ZeroInitialization(E);
7647 template<
typename ConditionalOperator>
7649 assert(Info.checkingPotentialConstantExpression());
7654 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7661 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
7668 Error(E, diag::note_constexpr_conditional_never_const);
7672 template<
typename ConditionalOperator>
7676 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
7677 CheckPotentialConstantConditional(E);
7680 if (Info.noteFailure()) {
7688 return StmtVisitorTy::Visit(EvalExpr);
7694 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
7697 return Info.CCEDiag(E, D);
7700 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
7702 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
7704 return BuiltinOp != 0 &&
7705 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
7709 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
7711 EvalInfo &getEvalInfo() {
return Info; }
7720 return Error(E, diag::note_invalid_subexpr_in_const_expr);
7723 bool VisitStmt(
const Stmt *) {
7724 llvm_unreachable(
"Expression evaluator should not be called on stmts");
7726 bool VisitExpr(
const Expr *E) {
7737 return StmtVisitorTy::Visit(E->
getSubExpr());
7741 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
7743 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
7745 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
7753 TempVersionRAII RAII(*Info.CurrentCall);
7754 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
7755 return StmtVisitorTy::Visit(E->
getExpr());
7758 TempVersionRAII RAII(*Info.CurrentCall);
7762 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
7763 return StmtVisitorTy::Visit(E->
getExpr());
7767 FullExpressionRAII
Scope(Info);
7774 return StmtVisitorTy::Visit(E->
getSubExpr());
7778 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
7779 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
7782 if (!Info.Ctx.getLangOpts().CPlusPlus20)
7783 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
7784 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
7787 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
7796 VisitIgnoredValue(E->
getLHS());
7797 return StmtVisitorTy::Visit(E->
getRHS());
7807 return DerivedSuccess(Result, E);
7820 if (!
Evaluate(Info.CurrentCall->createTemporary(
7823 ScopeKind::FullExpression, CommonLV),
7827 return HandleConditionalOperator(E);
7831 bool IsBcpCall =
false;
7838 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
7845 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
7848 FoldConstant Fold(Info, IsBcpCall);
7849 if (!HandleConditionalOperator(E)) {
7850 Fold.keepDiagnostics();
7858 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
7860 return DerivedSuccess(*
Value, E);
7866 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
7869 return StmtVisitorTy::Visit(Source);
7874 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
7883 if (OVE->isUnique())
7887 if (!
Evaluate(Info.CurrentCall->createTemporary(
7888 OVE, getStorageType(Info.Ctx, OVE),
7889 ScopeKind::FullExpression, LV),
7890 Info, OVE->getSourceExpr()))
7893 if (!StmtVisitorTy::Visit(SemE))
7903 bool VisitCallExpr(
const CallExpr *E) {
7905 if (!handleCallExpr(E, Result,
nullptr))
7907 return DerivedSuccess(Result, E);
7911 const LValue *ResultSlot) {
7912 CallScopeRAII CallScope(Info);
7918 LValue *
This =
nullptr, ThisVal;
7920 bool HasQualifier =
false;
7927 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
7931 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
7933 return Error(Callee);
7935 HasQualifier = ME->hasQualifier();
7936 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
7942 Member = dyn_cast<CXXMethodDecl>(D);
7944 return Error(Callee);
7946 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
7947 if (!Info.getLangOpts().CPlusPlus20)
7948 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
7952 return Error(Callee);
7959 if (!CalleeLV.getLValueOffset().isZero())
7960 return Error(Callee);
7961 if (CalleeLV.isNullPointer()) {
7962 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
7966 FD = dyn_cast_or_null<FunctionDecl>(
7967 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
7969 return Error(Callee);
7972 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
7979 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
7980 if (OCE && OCE->isAssignmentOp()) {
7981 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
7982 Call = Info.CurrentCall->createCall(FD);
7983 bool HasThis =
false;
7984 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
7985 HasThis = MD->isImplicitObjectMemberFunction();
8013 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8014 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8018 Args = Args.slice(1);
8027 "Number of captures must be zero for conversion to function-ptr");
8038 "A generic lambda's static-invoker function must be a "
8039 "template specialization");
8043 void *InsertPos =
nullptr;
8046 assert(CorrespondingCallOpSpecialization &&
8047 "We must always have a function call operator specialization "
8048 "that corresponds to our static invoker specialization");
8049 assert(isa<CXXMethodDecl>(CorrespondingCallOpSpecialization));
8050 FD = CorrespondingCallOpSpecialization;
8059 Ptr.moveInto(Result);
8060 return CallScope.destroy();
8070 Call = Info.CurrentCall->createCall(FD);
8077 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8078 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8081 CovariantAdjustmentPath);
8084 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8094 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8095 assert(This &&
"no 'this' pointer for destructor call");
8097 Info.Ctx.getRecordType(DD->getParent())) &&
8098 CallScope.destroy();
8106 Body, Info, Result, ResultSlot))
8109 if (!CovariantAdjustmentPath.empty() &&
8111 CovariantAdjustmentPath))
8114 return CallScope.destroy();
8122 return DerivedZeroInitialization(E);
8124 return StmtVisitorTy::Visit(E->
getInit(0));
8128 return DerivedZeroInitialization(E);
8131 return DerivedZeroInitialization(E);
8134 return DerivedZeroInitialization(E);
8139 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8140 "missing temporary materialization conversion");
8141 assert(!E->
isArrow() &&
"missing call to bound member function?");
8150 if (!FD)
return Error(E);
8164 DerivedSuccess(Result, E);
8175 if (Indices.size() == 1) {
8177 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8181 for (
unsigned I = 0; I < Indices.size(); ++I) {
8184 APValue VecResult(Elts.data(), Indices.size());
8185 return DerivedSuccess(VecResult, E);
8192 bool VisitCastExpr(
const CastExpr *E) {
8197 case CK_AtomicToNonAtomic: {
8204 return DerivedSuccess(AtomicVal, E);
8208 case CK_UserDefinedConversion:
8209 return StmtVisitorTy::Visit(E->
getSubExpr());
8211 case CK_LValueToRValue: {
8220 return DerivedSuccess(RVal, E);
8222 case CK_LValueToRValueBitCast: {
8223 APValue DestValue, SourceValue;
8226 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
8228 return DerivedSuccess(DestValue, E);
8231 case CK_AddressSpaceConversion: {
8235 return DerivedSuccess(
Value, E);
8243 return VisitUnaryPostIncDec(UO);
8246 return VisitUnaryPostIncDec(UO);
8249 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8259 return DerivedSuccess(RVal, UO);
8262 bool VisitStmtExpr(
const StmtExpr *E) {
8272 BlockScopeRAII
Scope(Info);
8277 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
8279 Info.FFDiag((*BI)->getBeginLoc(),
8280 diag::note_constexpr_stmt_expr_unsupported);
8283 return this->Visit(FinalExpr) &&
Scope.destroy();
8289 if (ESR != ESR_Succeeded) {
8293 if (ESR != ESR_Failed)
8294 Info.FFDiag((*BI)->getBeginLoc(),
8295 diag::note_constexpr_stmt_expr_unsupported);
8300 llvm_unreachable(
"Return from function from the loop above.");
8308 void VisitIgnoredValue(
const Expr *E) {
8313 void VisitIgnoredBaseExpression(
const Expr *E) {
8316 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
8318 VisitIgnoredValue(E);
8328template<
class Derived>
8329class LValueExprEvaluatorBase
8330 :
public ExprEvaluatorBase<Derived> {
8334 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
8335 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
8342 bool evaluatePointer(
const Expr *E, LValue &Result) {
8347 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
8348 : ExprEvaluatorBaseTy(Info), Result(Result),
8349 InvalidBaseOK(InvalidBaseOK) {}
8352 Result.setFrom(this->Info.Ctx,
V);
8361 EvalOK = evaluatePointer(E->
getBase(), Result);
8368 EvalOK = this->Visit(E->
getBase());
8374 Result.setInvalid(E);
8389 return this->
Error(E);
8404 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8412 bool VisitCastExpr(
const CastExpr *E) {
8415 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8417 case CK_DerivedToBase:
8418 case CK_UncheckedDerivedToBase:
8465class LValueExprEvaluator
8466 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
8468 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
8469 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
8471 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
8474 bool VisitCallExpr(
const CallExpr *E);
8489 return VisitUnaryPreIncDec(UO);
8492 return VisitUnaryPreIncDec(UO);
8497 bool VisitCastExpr(
const CastExpr *E) {
8500 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
8502 case CK_LValueBitCast:
8503 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
8504 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
8507 Result.Designator.setInvalid();
8510 case CK_BaseToDerived:
8527 bool LValueToRValueConversion) {
8531 assert(Info.CurrentCall->This ==
nullptr &&
8532 "This should not be set for a static call operator");
8540 if (Self->getType()->isReferenceType()) {
8541 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
8542 Result.setFrom(Info.Ctx, *RefValue);
8544 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
8545 CallStackFrame *Frame =
8546 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
8548 unsigned Version = Info.CurrentCall->Arguments.Version;
8549 Result.set({VD, Frame->Index, Version});
8552 Result = *Info.CurrentCall->This;
8562 if (LValueToRValueConversion) {
8566 Result.setFrom(Info.Ctx, RVal);
8577 bool InvalidBaseOK) {
8581 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
8584bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
8588 return Success(cast<ValueDecl>(D));
8589 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
8590 return VisitVarDecl(E, VD);
8591 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
8592 return Visit(BD->getBinding());
8597bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
8604 isa<DeclRefExpr>(E) &&
8605 cast<DeclRefExpr>(E)->refersToEnclosingVariableOrCapture()) {
8610 if (Info.checkingPotentialConstantExpression())
8613 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8614 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8620 CallStackFrame *Frame =
nullptr;
8621 unsigned Version = 0;
8629 CallStackFrame *CurrFrame = Info.CurrentCall;
8630 if (CurrFrame->Callee && CurrFrame->Callee->Equals(VD->
getDeclContext())) {
8634 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
8635 if (CurrFrame->Arguments) {
8636 VD = CurrFrame->Arguments.getOrigParam(PVD);
8638 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
8639 Version = CurrFrame->Arguments.Version;
8643 Version = CurrFrame->getCurrentTemporaryVersion(VD);
8650 Result.set({VD, Frame->Index, Version});
8656 if (!Info.getLangOpts().CPlusPlus11) {
8657 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
8659 Info.Note(VD->
getLocation(), diag::note_declared_at);
8665 if (!
V->hasValue()) {
8668 if (!Info.checkingPotentialConstantExpression())
8669 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
8675bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
8676 if (!IsConstantEvaluatedBuiltinCall(E))
8677 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8682 case Builtin::BIas_const:
8683 case Builtin::BIforward:
8684 case Builtin::BIforward_like:
8685 case Builtin::BImove:
8686 case Builtin::BImove_if_noexcept:
8688 return Visit(E->
getArg(0));
8692 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8695bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
8704 for (
const Expr *E : CommaLHSs)
8713 if (Info.EvalMode == EvalInfo::EM_ConstantFold)
8720 Value = &Info.CurrentCall->createTemporary(
8721 E, Inner->getType(),
8736 for (
unsigned I = Adjustments.size(); I != 0; ) {
8738 switch (Adjustments[I].Kind) {
8743 Type = Adjustments[I].DerivedToBase.BasePath->getType();
8749 Type = Adjustments[I].Field->getType();
8754 Adjustments[I].Ptr.RHS))
8756 Type = Adjustments[I].Ptr.MPT->getPointeeType();
8766 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
8767 "lvalue compound literal in c++?");
8773bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
8782 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
8783 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
8791 std::optional<DynamicType> DynType =
8797 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
8803bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
8807bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
8810 VisitIgnoredBaseExpression(E->
getBase());
8811 return VisitVarDecl(E, VD);
8816 if (MD->isStatic()) {
8817 VisitIgnoredBaseExpression(E->
getBase());
8823 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
8838 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr, Result)
8840 if (!Info.noteFailure())
8850bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
8851 return evaluatePointer(E->
getSubExpr(), Result);
8854bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
8863bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
8865 "lvalue __imag__ on scalar?");
8872bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
8873 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8884bool LValueExprEvaluator::VisitCompoundAssignOperator(
8886 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8894 if (!Info.noteFailure())
8909bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
8910 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
8918 if (!Info.noteFailure())
8926 if (Info.getLangOpts().CPlusPlus20 &&
8946 llvm::APInt &Result) {
8947 const AllocSizeAttr *AllocSize = getAllocSizeAttr(
Call);
8949 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
8950 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
8952 if (
Call->getNumArgs() <= SizeArgNo)
8955 auto EvaluateAsSizeT = [&](
const Expr *E,
APSInt &Into) {
8960 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
8962 Into = Into.zext(BitsInSizeT);
8967 if (!EvaluateAsSizeT(
Call->getArg(SizeArgNo), SizeOfElem))
8970 if (!AllocSize->getNumElemsParam().isValid()) {
8971 Result = std::move(SizeOfElem);
8976 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
8977 if (!EvaluateAsSizeT(
Call->getArg(NumArgNo), NumberOfElems))
8981 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
8985 Result = std::move(BytesAvailable);
8993 llvm::APInt &Result) {
8994 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
8995 "Can't get the size of a non alloc_size function");
8996 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9016 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9021 if (!
Init ||
Init->getType().isNull())
9024 const Expr *E =
Init->IgnoreParens();
9025 if (!tryUnwrapAllocSizeCall(E))
9030 Result.setInvalid(E);
9033 Result.addUnsizedArray(Info, E, Pointee);
9038class PointerExprEvaluator
9039 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9048 bool evaluateLValue(
const Expr *E, LValue &Result) {
9052 bool evaluatePointer(
const Expr *E, LValue &Result) {
9056 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9059 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
9060 : ExprEvaluatorBaseTy(info), Result(Result),
9061 InvalidBaseOK(InvalidBaseOK) {}
9064 Result.setFrom(Info.Ctx,
V);
9067 bool ZeroInitialization(
const Expr *E) {
9068 Result.setNull(Info.Ctx, E->
getType());
9073 bool VisitCastExpr(
const CastExpr* E);
9080 if (Info.noteFailure())
9086 bool VisitCallExpr(
const CallExpr *E);
9087 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9088 bool VisitBlockExpr(
const BlockExpr *E) {
9094 auto DiagnoseInvalidUseOfThis = [&] {
9095 if (Info.getLangOpts().CPlusPlus11)
9096 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9102 if (Info.checkingPotentialConstantExpression())
9105 bool IsExplicitLambda =
9107 if (!IsExplicitLambda) {
9108 if (!Info.CurrentCall->This) {
9109 DiagnoseInvalidUseOfThis();
9113 Result = *Info.CurrentCall->This;
9121 if (!Info.CurrentCall->LambdaThisCaptureField) {
9122 if (IsExplicitLambda && !Info.CurrentCall->This) {
9123 DiagnoseInvalidUseOfThis();
9130 const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
9132 Info, E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
9133 Info.CurrentCall->LambdaThisCaptureField->getType()->isPointerType());
9141 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
9143 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9144 Result.setFrom(Info.Ctx, LValResult);
9152 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
9153 ResultStr.size() + 1);
9154 QualType ArrayTy = Info.Ctx.getConstantArrayType(
9155 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
9161 evaluateLValue(SL, Result);
9162 Result.addArray(Info, E, cast<ConstantArrayType>(ArrayTy));
9171 bool InvalidBaseOK) {
9174 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
9177bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9180 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9185 std::swap(PExp, IExp);
9187 bool EvalPtrOK = evaluatePointer(PExp, Result);
9188 if (!EvalPtrOK && !Info.noteFailure())
9191 llvm::APSInt Offset;
9202bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
9203 return evaluateLValue(E->
getSubExpr(), Result);
9211 if (!FnII || !FnII->
isStr(
"current"))
9214 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
9222bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9229 case CK_CPointerToObjCPointerCast:
9230 case CK_BlockPointerToObjCPointerCast:
9231 case CK_AnyPointerToBlockPointerCast:
9232 case CK_AddressSpaceConversion:
9233 if (!Visit(SubExpr))
9241 bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid &&
9243 bool VoidPtrCastMaybeOK =
9246 Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx),
9255 if (VoidPtrCastMaybeOK &&
9256 (Info.getStdAllocatorCaller(
"allocate") ||
9258 Info.getLangOpts().CPlusPlus26)) {
9262 Info.getLangOpts().CPlusPlus) {
9264 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
9265 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
9266 << Result.Designator.getType(Info.Ctx).getCanonicalType()
9269 CCEDiag(E, diag::note_constexpr_invalid_cast)
9272 CCEDiag(E, diag::note_constexpr_invalid_cast)
9273 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9274 Result.Designator.setInvalid();
9277 if (E->
getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
9278 ZeroInitialization(E);
9281 case CK_DerivedToBase:
9282 case CK_UncheckedDerivedToBase:
9283 if (!evaluatePointer(E->
getSubExpr(), Result))
9285 if (!Result.Base && Result.Offset.isZero())
9294 case CK_BaseToDerived:
9297 if (!Result.Base && Result.Offset.isZero())
9306 case CK_NullToPointer:
9308 return ZeroInitialization(E);
9310 case CK_IntegralToPointer: {
9311 CCEDiag(E, diag::note_constexpr_invalid_cast)
9312 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
9318 if (
Value.isInt()) {
9319 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
9320 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
9321 Result.Base = (
Expr*)
nullptr;
9322 Result.InvalidBase =
false;
9324 Result.Designator.setInvalid();
9325 Result.IsNullPtr =
false;
9329 Result.setFrom(Info.Ctx,
Value);
9334 case CK_ArrayToPointerDecay: {
9336 if (!evaluateLValue(SubExpr, Result))
9340 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression, Result);
9345 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
9346 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
9347 Result.addArray(Info, E, CAT);
9349 Result.addUnsizedArray(Info, E, AT->getElementType());
9353 case CK_FunctionToPointerDecay:
9354 return evaluateLValue(SubExpr, Result);
9356 case CK_LValueToRValue: {
9365 return InvalidBaseOK &&
9371 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9379 T =
T.getNonReferenceType();
9381 if (
T.getQualifiers().hasUnaligned())
9384 const bool AlignOfReturnsPreferred =
9385 Info.Ctx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
9390 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
9391 return Info.Ctx.toCharUnitsFromBits(
9392 Info.Ctx.getPreferredTypeAlign(
T.getTypePtr()));
9394 else if (ExprKind == UETT_AlignOf)
9395 return Info.Ctx.getTypeAlignInChars(
T.getTypePtr());
9397 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
9410 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
9411 return Info.Ctx.getDeclAlign(DRE->getDecl(),
9414 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
9415 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
9423 return Info.Ctx.getDeclAlign(VD);
9424 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
9432 EvalInfo &Info,
APSInt &Alignment) {
9435 if (Alignment < 0 || !Alignment.isPowerOf2()) {
9436 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
9439 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
9440 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
9441 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
9442 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
9443 << MaxValue << ForType << Alignment;
9449 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
9450 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
9451 "Alignment should not be changed by ext/trunc");
9452 Alignment = ExtAlignment;
9453 assert(Alignment.getBitWidth() == SrcWidth);
9458bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
9459 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
9462 if (!(InvalidBaseOK && getAllocSizeAttr(E)))
9465 Result.setInvalid(E);
9467 Result.addUnsizedArray(Info, E, PointeeTy);
9471bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9472 if (!IsConstantEvaluatedBuiltinCall(E))
9473 return visitNonBuiltinCallExpr(E);
9483bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
9484 unsigned BuiltinOp) {
9488 switch (BuiltinOp) {
9489 case Builtin::BIaddressof:
9490 case Builtin::BI__addressof:
9491 case Builtin::BI__builtin_addressof:
9492 return evaluateLValue(E->
getArg(0), Result);
9493 case Builtin::BI__builtin_assume_aligned: {
9497 if (!evaluatePointer(E->
getArg(0), Result))
9500 LValue OffsetResult(Result);
9512 int64_t AdditionalOffset = -Offset.getZExtValue();
9517 if (OffsetResult.Base) {
9520 if (BaseAlignment < Align) {
9521 Result.Designator.setInvalid();
9524 diag::note_constexpr_baa_insufficient_alignment) << 0
9532 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
9533 Result.Designator.setInvalid();
9537 diag::note_constexpr_baa_insufficient_alignment) << 1
9539 diag::note_constexpr_baa_value_insufficient_alignment))
9540 << (
int)OffsetResult.Offset.getQuantity()
9547 case Builtin::BI__builtin_align_up:
9548 case Builtin::BI__builtin_align_down: {
9549 if (!evaluatePointer(E->
getArg(0), Result))
9568 assert(Alignment.getBitWidth() <= 64 &&
9569 "Cannot handle > 64-bit address-space");
9570 uint64_t Alignment64 = Alignment.getZExtValue();
9572 BuiltinOp == Builtin::BI__builtin_align_down
9573 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
9574 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
9575 Result.adjustOffset(NewOffset - Result.Offset);
9580 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
9584 case Builtin::BI__builtin_operator_new:
9586 case Builtin::BI__builtin_launder:
9587 return evaluatePointer(E->
getArg(0), Result);
9588 case Builtin::BIstrchr:
9589 case Builtin::BIwcschr:
9590 case Builtin::BImemchr:
9591 case Builtin::BIwmemchr:
9592 if (Info.getLangOpts().CPlusPlus11)
9593 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9595 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9597 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
9599 case Builtin::BI__builtin_strchr:
9600 case Builtin::BI__builtin_wcschr:
9601 case Builtin::BI__builtin_memchr:
9602 case Builtin::BI__builtin_char_memchr:
9603 case Builtin::BI__builtin_wmemchr: {
9604 if (!Visit(E->
getArg(0)))
9610 if (BuiltinOp != Builtin::BIstrchr &&
9611 BuiltinOp != Builtin::BIwcschr &&
9612 BuiltinOp != Builtin::BI__builtin_strchr &&
9613 BuiltinOp != Builtin::BI__builtin_wcschr) {
9617 MaxLength = N.getZExtValue();
9620 if (MaxLength == 0u)
9621 return ZeroInitialization(E);
9622 if (!Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
9623 Result.Designator.Invalid)
9625 QualType CharTy = Result.Designator.getType(Info.Ctx);
9626 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
9627 BuiltinOp == Builtin::BI__builtin_memchr;
9629 Info.Ctx.hasSameUnqualifiedType(
9633 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
9639 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
9640 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
9647 bool StopAtNull =
false;
9648 switch (BuiltinOp) {
9649 case Builtin::BIstrchr:
9650 case Builtin::BI__builtin_strchr:
9657 return ZeroInitialization(E);
9660 case Builtin::BImemchr:
9661 case Builtin::BI__builtin_memchr:
9662 case Builtin::BI__builtin_char_memchr:
9666 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
9669 case Builtin::BIwcschr:
9670 case Builtin::BI__builtin_wcschr:
9673 case Builtin::BIwmemchr:
9674 case Builtin::BI__builtin_wmemchr:
9676 DesiredVal = Desired.getZExtValue();
9680 for (; MaxLength; --MaxLength) {
9685 if (Char.
getInt().getZExtValue() == DesiredVal)
9687 if (StopAtNull && !Char.
getInt())
9693 return ZeroInitialization(E);
9696 case Builtin::BImemcpy:
9697 case Builtin::BImemmove:
9698 case Builtin::BIwmemcpy:
9699 case Builtin::BIwmemmove:
9700 if (Info.getLangOpts().CPlusPlus11)
9701 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9703 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
9705 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
9707 case Builtin::BI__builtin_memcpy:
9708 case Builtin::BI__builtin_memmove:
9709 case Builtin::BI__builtin_wmemcpy:
9710 case Builtin::BI__builtin_wmemmove: {
9711 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
9712 BuiltinOp == Builtin::BIwmemmove ||
9713 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
9714 BuiltinOp == Builtin::BI__builtin_wmemmove;
9715 bool Move = BuiltinOp == Builtin::BImemmove ||
9716 BuiltinOp == Builtin::BIwmemmove ||
9717 BuiltinOp == Builtin::BI__builtin_memmove ||
9718 BuiltinOp == Builtin::BI__builtin_wmemmove;
9721 if (!Visit(E->
getArg(0)))
9723 LValue Dest = Result;
9732 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
9742 if (!Src.Base || !Dest.Base) {
9744 (!Src.Base ? Src : Dest).moveInto(Val);
9745 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
9746 <<
Move << WChar << !!Src.Base
9750 if (Src.Designator.Invalid || Dest.Designator.Invalid)
9756 QualType T = Dest.Designator.getType(Info.Ctx);
9757 QualType SrcT = Src.Designator.getType(Info.Ctx);
9758 if (!Info.Ctx.hasSameUnqualifiedType(
T, SrcT)) {
9760 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT <<
T;
9764 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move <<
T;
9767 if (!
T.isTriviallyCopyableType(Info.Ctx)) {
9768 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move <<
T;
9773 uint64_t TSize = Info.Ctx.getTypeSizeInChars(
T).getQuantity();
9778 llvm::APInt OrigN = N;
9779 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
9781 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
9791 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
9792 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
9793 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
9794 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
9795 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) <<
T
9799 uint64_t NElems = N.getZExtValue();
9805 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
9806 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
9807 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
9810 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
9818 }
else if (!Move && SrcOffset >= DestOffset &&
9819 SrcOffset - DestOffset < NBytes) {
9821 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
9856bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
9857 if (!Info.getLangOpts().CPlusPlus20)
9858 Info.CCEDiag(E, diag::note_constexpr_new);
9861 if (Info.SpeculativeEvaluationDepth)
9866 bool IsNothrow =
false;
9867 bool IsPlacement =
false;
9869 Info.CurrentCall->isStdFunction() && !E->
isArray()) {
9874 if (Result.Designator.Invalid)
9878 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
9879 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
9894 return Error(E, diag::note_constexpr_new_placement);
9905 bool ValueInit =
false;
9908 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
9909 const Expr *Stripped = *ArraySize;
9910 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
9911 Stripped = ICE->getSubExpr())
9912 if (ICE->getCastKind() != CK_NoOp &&
9913 ICE->getCastKind() != CK_IntegralCast)
9916 llvm::APSInt ArrayBound;
9924 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
9926 return ZeroInitialization(E);
9928 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
9929 << ArrayBound << (*ArraySize)->getSourceRange();
9935 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
9937 Info.Ctx, AllocType, ArrayBound),
9938 ArrayBound.getZExtValue(), !IsNothrow)) {
9940 return ZeroInitialization(E);
9949 }
else if (isa<CXXScalarValueInitExpr>(
Init) ||
9950 isa<ImplicitValueInitExpr>(
Init)) {
9952 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
9953 ResizedArrayCCE = CCE;
9955 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
9956 assert(CAT &&
"unexpected type for array initializer");
9960 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
9961 llvm::APInt AllocBound = ArrayBound.zext(Bits);
9962 if (InitBound.ugt(AllocBound)) {
9964 return ZeroInitialization(E);
9966 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
9969 << (*ArraySize)->getSourceRange();
9975 if (InitBound != AllocBound)
9976 ResizedArrayILE = cast<InitListExpr>(
Init);
9979 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
9980 ArraySizeModifier::Normal, 0);
9983 "array allocation with non-array new");
9989 struct FindObjectHandler {
9996 typedef bool result_type;
9997 bool failed() {
return false; }
10001 if (!Info.Ctx.hasSameUnqualifiedType(SubobjType, AllocType)) {
10002 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type) <<
10003 SubobjType << AllocType;
10010 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10014 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
10017 } Handler = {Info, E, AllocType, AK,
nullptr};
10020 if (!Obj || !
findSubobject(Info, E, Obj, Result.Designator, Handler))
10023 Val = Handler.Value;
10032 Val = Info.createHeapAlloc(E, AllocType, Result);
10041 }
else if (ResizedArrayILE) {
10045 }
else if (ResizedArrayCCE) {
10059 Result.addArray(Info, E, cast<ConstantArrayType>(AT));
10068class MemberPointerExprEvaluator
10069 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
10073 Result = MemberPtr(D);
10078 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
10079 : ExprEvaluatorBaseTy(Info), Result(Result) {}
10085 bool ZeroInitialization(
const Expr *E) {
10089 bool VisitCastExpr(
const CastExpr *E);
10098 return MemberPointerExprEvaluator(Info, Result).Visit(E);
10101bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10104 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10106 case CK_NullToMemberPointer:
10108 return ZeroInitialization(E);
10110 case CK_BaseToDerivedMemberPointer: {
10118 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
10120 PathI != PathE; ++PathI) {
10121 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10122 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
10123 if (!Result.castToDerived(Derived))
10132 case CK_DerivedToBaseMemberPointer:
10136 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10137 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
10139 if (!Result.castToBase(
Base))
10146bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10157 class RecordExprEvaluator
10158 :
public ExprEvaluatorBase<RecordExprEvaluator> {
10159 const LValue &
This;
10163 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
10164 : ExprEvaluatorBaseTy(info),
This(
This), Result(Result) {}
10170 bool ZeroInitialization(
const Expr *E) {
10171 return ZeroInitialization(E, E->
getType());
10175 bool VisitCallExpr(
const CallExpr *E) {
10176 return handleCallExpr(E, Result, &This);
10178 bool VisitCastExpr(
const CastExpr *E);
10181 return VisitCXXConstructExpr(E, E->
getType());
10189 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
10203 const LValue &This,
APValue &Result) {
10204 assert(!RD->
isUnion() &&
"Expected non-union class type");
10213 unsigned Index = 0;
10215 End = CD->
bases_end(); I != End; ++I, ++Index) {
10217 LValue Subobject = This;
10221 Result.getStructBase(Index)))
10226 for (
const auto *I : RD->
fields()) {
10228 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
10231 LValue Subobject = This;
10237 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
10244bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
10251 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
10258 LValue Subobject =
This;
10263 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
10266 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
10267 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
10274bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10277 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10279 case CK_ConstructorConversion:
10282 case CK_DerivedToBase:
10283 case CK_UncheckedDerivedToBase: {
10294 PathE = E->
path_end(); PathI != PathE; ++PathI) {
10295 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
10306bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10309 return VisitCXXParenListOrInitListExpr(E, E->
inits());
10312bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
10318 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
10320 EvalInfo::EvaluatingConstructorRAII EvalObj(
10322 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
10323 CXXRD && CXXRD->getNumBases());
10327 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
10328 Field = ILE->getInitializedFieldInUnion();
10329 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
10330 Field = PLIE->getInitializedFieldInUnion();
10333 "Expression is neither an init list nor a C++ paren list");
10346 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
10348 LValue Subobject =
This;
10353 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10354 isa<CXXDefaultInitExpr>(InitExpr));
10356 if (
EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr)) {
10357 if (
Field->isBitField())
10366 if (!Result.hasValue())
10369 unsigned ElementNo = 0;
10373 if (CXXRD && CXXRD->getNumBases()) {
10374 for (
const auto &
Base : CXXRD->bases()) {
10375 assert(ElementNo < Args.size() &&
"missing init for base class");
10376 const Expr *
Init = Args[ElementNo];
10378 LValue Subobject =
This;
10382 APValue &FieldVal = Result.getStructBase(ElementNo);
10384 if (!Info.noteFailure())
10391 EvalObj.finishedConstructingBases();
10395 for (
const auto *Field : RD->
fields()) {
10398 if (
Field->isUnnamedBitField())
10401 LValue Subobject =
This;
10403 bool HaveInit = ElementNo < Args.size();
10408 Subobject, Field, &Layout))
10414 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
10416 if (
Field->getType()->isIncompleteArrayType()) {
10417 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
10421 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
10428 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
10429 isa<CXXDefaultInitExpr>(
Init));
10431 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10434 FieldVal, Field))) {
10435 if (!Info.noteFailure())
10441 EvalObj.finishedConstructingFields();
10456 if (Result.hasValue())
10460 return ZeroInitialization(E,
T);
10480 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
10482 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
10483 return Visit(ME->getSubExpr());
10486 if (ZeroInit && !ZeroInitialization(E,
T))
10495bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
10497 if (!Info.CurrentCall) {
10498 assert(Info.checkingPotentialConstantExpression());
10517bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
10526 assert(
ArrayType &&
"unexpected type for array initializer");
10531 auto InvalidType = [&] {
10532 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
10540 if (Field ==
Record->field_end())
10541 return InvalidType();
10544 if (!
Field->getType()->isPointerType() ||
10545 !Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10547 return InvalidType();
10551 Array.moveInto(Result.getStructField(0));
10553 if (++Field ==
Record->field_end())
10554 return InvalidType();
10556 if (
Field->getType()->isPointerType() &&
10557 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
10564 Array.moveInto(Result.getStructField(1));
10565 }
else if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType()))
10569 return InvalidType();
10571 if (++Field !=
Record->field_end())
10572 return InvalidType();
10577bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
10582 const size_t NumFields =
10587 "The number of lambda capture initializers should equal the number of "
10588 "fields within the closure type");
10595 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
10596 for (
const auto *Field : ClosureClass->
fields()) {
10599 Expr *
const CurFieldInit = *CaptureInitIt++;
10606 LValue Subobject =
This;
10611 APValue &FieldVal = Result.getStructField(
Field->getFieldIndex());
10613 if (!Info.keepEvaluatingAfterFailure())
10622 APValue &Result, EvalInfo &Info) {
10625 "can't evaluate expression as a record rvalue");
10626 return RecordExprEvaluator(Info, This, Result).Visit(E);
10637class TemporaryExprEvaluator
10638 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
10640 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
10641 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
10644 bool VisitConstructExpr(
const Expr *E) {
10646 E, E->
getType(), ScopeKind::FullExpression, Result);
10650 bool VisitCastExpr(
const CastExpr *E) {
10653 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
10655 case CK_ConstructorConversion:
10660 return VisitConstructExpr(E);
10663 return VisitConstructExpr(E);
10665 bool VisitCallExpr(
const CallExpr *E) {
10666 return VisitConstructExpr(E);
10669 return VisitConstructExpr(E);
10672 return VisitConstructExpr(E);
10681 return TemporaryExprEvaluator(Info, Result).Visit(E);
10689 class VectorExprEvaluator
10690 :
public ExprEvaluatorBase<VectorExprEvaluator> {
10694 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
10695 : ExprEvaluatorBaseTy(info), Result(Result) {}
10704 assert(
V.isVector());
10708 bool ZeroInitialization(
const Expr *E);
10712 bool VisitCastExpr(
const CastExpr* E);
10727 "not a vector prvalue");
10728 return VectorExprEvaluator(Info, Result).Visit(E);
10731bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10739 case CK_VectorSplat: {
10745 Val =
APValue(std::move(IntResult));
10750 Val =
APValue(std::move(FloatResult));
10767 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
10768 << 2 << Info.Ctx.getLangOpts().CPlusPlus;
10772 if (!handleRValueToRValueBitCast(Info, Result, SVal, E))
10778 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10783VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10795 unsigned CountInits = 0, CountElts = 0;
10796 while (CountElts < NumElements) {
10798 if (CountInits < NumInits
10803 unsigned vlen =
v.getVectorLength();
10804 for (
unsigned j = 0; j < vlen; j++)
10805 Elements.push_back(
v.getVectorElt(j));
10808 llvm::APSInt sInt(32);
10809 if (CountInits < NumInits) {
10813 sInt = Info.Ctx.MakeIntValue(0, EltTy);
10814 Elements.push_back(
APValue(sInt));
10817 llvm::APFloat f(0.0);
10818 if (CountInits < NumInits) {
10822 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
10823 Elements.push_back(
APValue(f));
10832VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
10836 if (EltTy->isIntegerType())
10837 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
10840 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
10846bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
10848 return ZeroInitialization(E);
10851bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10853 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
10854 "Operation not supported on vector types");
10856 if (Op == BO_Comma)
10857 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10863 "Must both be vector types");
10870 "All operands must be the same size.");
10874 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
10875 if (!LHSOK && !Info.noteFailure())
10877 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
10899 "Vector can only be int or float type");
10907 "Vector operator ~ can only be int");
10908 Elt.
getInt().flipAllBits();
10918 "Vector can only be int or float type");
10924 EltResult.setAllBits();
10926 EltResult.clearAllBits();
10932 return std::nullopt;
10936bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
10942 const QualType ResultEltTy = VD->getElementType();
10946 if (!
Evaluate(SubExprValue, Info, SubExpr))
10959 "Vector length doesn't match type?");
10962 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
10964 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
10967 ResultElements.push_back(*Elt);
10969 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
10978 Result =
APValue(APFloat(0.0));
10980 DestTy, Result.getFloat());
10991 Result.getFloat());
10996 DestTy, Result.getInt());
11000 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
11001 << SourceTy << DestTy;
11018 ResultElements.reserve(SourceLen);
11019 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11024 ResultElements.push_back(std::move(Elt));
11027 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11032 APValue const &VecVal2,
unsigned EltNum,
11034 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
11035 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
11038 int64_t index = IndexVal.getExtValue();
11045 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
11051 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
11052 llvm_unreachable(
"Out of bounds shuffle index");
11054 if (index >= TotalElementsInInputVector1)
11055 Result = VecVal2.
getVectorElt(index - TotalElementsInInputVector1);
11077 ResultElements.reserve(TotalElementsInOutputVector);
11078 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
11082 ResultElements.push_back(std::move(Elt));
11085 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
11093 class ArrayExprEvaluator
11094 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
11095 const LValue &
This;
11099 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
11100 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
11103 assert(
V.isArray() &&
"expected array");
11108 bool ZeroInitialization(
const Expr *E) {
11110 Info.Ctx.getAsConstantArrayType(E->
getType());
11124 if (!Result.hasArrayFiller())
11128 LValue Subobject =
This;
11129 Subobject.addArray(Info, E, CAT);
11131 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
11134 bool VisitCallExpr(
const CallExpr *E) {
11135 return handleCallExpr(E, Result, &This);
11142 const LValue &Subobject,
11150 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11152 const Expr *ArrayFiller,
11158 APValue &Result, EvalInfo &Info) {
11161 "not an array prvalue");
11162 return ArrayExprEvaluator(Info, This, Result).Visit(E);
11170 "not an array prvalue");
11171 return ArrayExprEvaluator(Info, This, Result)
11172 .VisitInitListExpr(ILE, AllocType);
11181 "not an array prvalue");
11182 return ArrayExprEvaluator(Info, This, Result)
11183 .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
11190 if (isa<ImplicitValueInitExpr>(FillerExpr))
11192 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
11193 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
11198 if (ILE->hasArrayFiller() &&
11207bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
11222 return VisitStringLiteral(SL, AllocType);
11227 "transparent array list initialization is not string literal init?");
11233bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
11241 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
11242 "zero-initialized array shouldn't have any initialized elts");
11244 if (Result.isArray() && Result.hasArrayFiller())
11245 Filler = Result.getArrayFiller();
11247 unsigned NumEltsToInit = Args.size();
11253 NumEltsToInit = NumElts;
11255 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
11256 << NumEltsToInit <<
".\n");
11263 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I)
11264 Result.getArrayInitializedElt(I) = Filler;
11265 if (Result.hasArrayFiller())
11266 Result.getArrayFiller() = Filler;
11269 LValue Subobject =
This;
11270 Subobject.addArray(Info, ExprToVisit, CAT);
11271 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
11272 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
11274 Info, Subobject,
Init) ||
11277 if (!Info.noteFailure())
11283 if (!Result.hasArrayFiller())
11288 assert(ArrayFiller &&
"no array filler for incomplete init list");
11297 !
Evaluate(Info.CurrentCall->createTemporary(
11300 ScopeKind::FullExpression, CommonLV),
11309 LValue Subobject =
This;
11310 Subobject.addArray(Info, E, CAT);
11313 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
11322 FullExpressionRAII
Scope(Info);
11328 if (!Info.noteFailure())
11340bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11341 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
11345 const LValue &Subobject,
11355 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
11359 if (FinalSize == 0)
11365 LValue ArrayElt = Subobject;
11366 ArrayElt.addArray(Info, E, CAT);
11372 for (
const unsigned N : {1u, FinalSize}) {
11373 unsigned OldElts =
Value->getArrayInitializedElts();
11379 for (
unsigned I = 0; I < OldElts; ++I)
11380 NewValue.getArrayInitializedElt(I).swap(
11381 Value->getArrayInitializedElt(I));
11382 Value->swap(NewValue);
11385 for (
unsigned I = OldElts; I < N; ++I)
11386 Value->getArrayInitializedElt(I) = Filler;
11388 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
11391 APValue &FirstResult =
Value->getArrayInitializedElt(0);
11392 for (
unsigned I = OldElts; I < FinalSize; ++I)
11393 Value->getArrayInitializedElt(I) = FirstResult;
11395 for (
unsigned I = OldElts; I < N; ++I) {
11396 if (!VisitCXXConstructExpr(E, ArrayElt,
11397 &
Value->getArrayInitializedElt(I),
11404 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
11405 !Info.keepEvaluatingAfterFailure())
11417 return RecordExprEvaluator(Info, Subobject, *
Value)
11418 .VisitCXXConstructExpr(E,
Type);
11421bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
11423 assert(dyn_cast<ConstantArrayType>(E->
getType()) &&
11424 "Expression result is not a constant array type");
11426 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
11439class IntExprEvaluator
11440 :
public ExprEvaluatorBase<IntExprEvaluator> {
11443 IntExprEvaluator(EvalInfo &info,
APValue &result)
11444 : ExprEvaluatorBaseTy(info), Result(result) {}
11448 "Invalid evaluation result.");
11450 "Invalid evaluation result.");
11451 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
11452 "Invalid evaluation result.");
11456 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
11457 return Success(SI, E, Result);
11462 "Invalid evaluation result.");
11463 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
11464 "Invalid evaluation result.");
11466 Result.getInt().setIsUnsigned(
11470 bool Success(
const llvm::APInt &I,
const Expr *E) {
11471 return Success(I, E, Result);
11476 "Invalid evaluation result.");
11489 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate()) {
11496 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
11509 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
11511 if (CheckReferencedDecl(E, E->
getDecl()))
11514 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
11518 VisitIgnoredBaseExpression(E->
getBase());
11522 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
11525 bool VisitCallExpr(
const CallExpr *E);
11526 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
11531 bool VisitCastExpr(
const CastExpr* E);
11543 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
11549 return Success(Info.ArrayInitIndex, E);
11554 return ZeroInitialization(E);
11580class FixedPointExprEvaluator
11581 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
11585 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
11586 : ExprEvaluatorBaseTy(info), Result(result) {}
11588 bool Success(
const llvm::APInt &I,
const Expr *E) {
11590 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
11595 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
11599 return Success(
V.getFixedPoint(), E);
11604 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
11605 "Invalid evaluation result.");
11610 bool ZeroInitialization(
const Expr *E) {
11622 bool VisitCastExpr(
const CastExpr *E);
11640 return IntExprEvaluator(Info, Result).Visit(E);
11648 if (!Val.
isInt()) {
11651 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
11658bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
11660 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
11669 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
11684 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
11688 Result = APFixedPoint(Val, FXSema);
11699bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
11703 bool SameSign = (ECD->getInitVal().isSigned()
11705 bool SameWidth = (ECD->getInitVal().getBitWidth()
11706 == Info.Ctx.getIntWidth(E->
getType()));
11707 if (SameSign && SameWidth)
11708 return Success(ECD->getInitVal(), E);
11712 llvm::APSInt Val = ECD->getInitVal();
11714 Val.setIsSigned(!ECD->getInitVal().isSigned());
11716 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
11732#define TYPE(ID, BASE)
11733#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
11734#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
11735#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
11736#include "clang/AST/TypeNodes.inc"
11738 case Type::DeducedTemplateSpecialization:
11739 llvm_unreachable(
"unexpected non-canonical or dependent type");
11741 case Type::Builtin:
11742 switch (cast<BuiltinType>(CanTy)->
getKind()) {
11743#define BUILTIN_TYPE(ID, SINGLETON_ID)
11744#define SIGNED_TYPE(ID, SINGLETON_ID) \
11745 case BuiltinType::ID: return GCCTypeClass::Integer;
11746#define FLOATING_TYPE(ID, SINGLETON_ID) \
11747 case BuiltinType::ID: return GCCTypeClass::RealFloat;
11748#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
11749 case BuiltinType::ID: break;
11750#include "clang/AST/BuiltinTypes.def"
11751 case BuiltinType::Void:
11752 return GCCTypeClass::Void;
11754 case BuiltinType::Bool:
11755 return GCCTypeClass::Bool;
11757 case BuiltinType::Char_U:
11758 case BuiltinType::UChar:
11759 case BuiltinType::WChar_U:
11760 case BuiltinType::Char8:
11761 case BuiltinType::Char16:
11762 case BuiltinType::Char32:
11763 case BuiltinType::UShort:
11764 case BuiltinType::UInt:
11765 case BuiltinType::ULong:
11766 case BuiltinType::ULongLong:
11767 case BuiltinType::UInt128:
11768 return GCCTypeClass::Integer;
11770 case BuiltinType::UShortAccum:
11771 case BuiltinType::UAccum:
11772 case BuiltinType::ULongAccum:
11773 case BuiltinType::UShortFract:
11774 case BuiltinType::UFract:
11775 case BuiltinType::ULongFract:
11776 case BuiltinType::SatUShortAccum:
11777 case BuiltinType::SatUAccum:
11778 case BuiltinType::SatULongAccum:
11779 case BuiltinType::SatUShortFract:
11780 case BuiltinType::SatUFract:
11781 case BuiltinType::SatULongFract:
11782 return GCCTypeClass::None;
11784 case BuiltinType::NullPtr:
11786 case BuiltinType::ObjCId:
11787 case BuiltinType::ObjCClass:
11788 case BuiltinType::ObjCSel:
11789#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
11790 case BuiltinType::Id:
11791#include "clang/Basic/OpenCLImageTypes.def"
11792#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
11793 case BuiltinType::Id:
11794#include "clang/Basic/OpenCLExtensionTypes.def"
11795 case BuiltinType::OCLSampler:
11796 case BuiltinType::OCLEvent:
11797 case BuiltinType::OCLClkEvent:
11798 case BuiltinType::OCLQueue:
11799 case BuiltinType::OCLReserveID:
11800#define SVE_TYPE(Name, Id, SingletonId) \
11801 case BuiltinType::Id:
11802#include "clang/Basic/AArch64SVEACLETypes.def"
11803#define PPC_VECTOR_TYPE(Name, Id, Size) \
11804 case BuiltinType::Id:
11805#include "clang/Basic/PPCTypes.def"
11806#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11807#include "clang/Basic/RISCVVTypes.def"
11808#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
11809#include "clang/Basic/WebAssemblyReferenceTypes.def"
11810 return GCCTypeClass::None;
11812 case BuiltinType::Dependent:
11813 llvm_unreachable(
"unexpected dependent type");
11815 llvm_unreachable(
"unexpected placeholder type");
11818 return LangOpts.CPlusPlus ? GCCTypeClass::Enum : GCCTypeClass::Integer;
11820 case Type::Pointer:
11821 case Type::ConstantArray:
11822 case Type::VariableArray:
11823 case Type::IncompleteArray:
11824 case Type::FunctionNoProto:
11825 case Type::FunctionProto:
11826 case Type::ArrayParameter:
11827 return GCCTypeClass::Pointer;
11829 case Type::MemberPointer:
11831 ? GCCTypeClass::PointerToDataMember
11832 : GCCTypeClass::PointerToMemberFunction;
11834 case Type::Complex:
11835 return GCCTypeClass::Complex;
11838 return CanTy->
isUnionType() ? GCCTypeClass::Union
11839 : GCCTypeClass::ClassOrStruct;
11847 case Type::ExtVector:
11848 return GCCTypeClass::Vector;
11850 case Type::BlockPointer:
11851 case Type::ConstantMatrix:
11852 case Type::ObjCObject:
11853 case Type::ObjCInterface:
11854 case Type::ObjCObjectPointer:
11858 return GCCTypeClass::None;
11861 return GCCTypeClass::BitInt;
11863 case Type::LValueReference:
11864 case Type::RValueReference:
11865 llvm_unreachable(
"invalid type for expression");
11868 llvm_unreachable(
"unexpected type class");
11878 return GCCTypeClass::None;
11893 if (
Base.isNull()) {
11896 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
11897 if (!isa<StringLiteral>(E))
11915 SpeculativeEvaluationRAII SpeculativeEval(Info);
11920 FoldConstant Fold(Info,
true);
11943 Fold.keepDiagnostics();
11952 return V.hasValue();
11963 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
11966 if (isa<CompoundLiteralExpr>(E))
11987 const auto *Cast = dyn_cast<CastExpr>(NoParens);
11988 if (Cast ==
nullptr)
11993 auto CastKind = Cast->getCastKind();
11995 CastKind != CK_AddressSpaceConversion)
11998 const auto *SubExpr = Cast->getSubExpr();
12020 assert(!LVal.Designator.Invalid);
12022 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &
Invalid) {
12031 auto &
Base = LVal.getLValueBase();
12032 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
12033 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
12035 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12037 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
12038 for (
auto *FD : IFD->chain()) {
12040 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD),
Invalid))
12048 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
12058 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
12059 const auto &Entry = LVal.Designator.Entries[I];
12065 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
12066 uint64_t Index = Entry.getAsArrayIndex();
12072 uint64_t Index = Entry.getAsArrayIndex();
12075 BaseType = CT->getElementType();
12076 }
else if (
auto *FD = getAsField(Entry)) {
12078 if (!IsLastOrInvalidFieldDecl(FD,
Invalid))
12082 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
12094 if (LVal.Designator.Invalid)
12097 if (!LVal.Designator.Entries.empty())
12098 return LVal.Designator.isMostDerivedAnUnsizedArray();
12100 if (!LVal.InvalidBase)
12105 const auto *E = LVal.Base.dyn_cast<
const Expr *>();
12106 return !E || !isa<MemberExpr>(E);
12112 const SubobjectDesignator &
Designator = LVal.Designator;
12124 auto isFlexibleArrayMember = [&] {
12126 FAMKind StrictFlexArraysLevel =
12129 if (
Designator.isMostDerivedAnUnsizedArray())
12132 if (StrictFlexArraysLevel == FAMKind::Default)
12135 if (
Designator.getMostDerivedArraySize() == 0 &&
12136 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
12139 if (
Designator.getMostDerivedArraySize() == 1 &&
12140 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
12146 return LVal.InvalidBase &&
12148 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
12156 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
12157 if (Int.ugt(CharUnitsMax))
12169 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
12170 if (
const auto *VD = dyn_cast<VarDecl>(
V))
12182 unsigned Type,
const LValue &LVal,
12195 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
12197 if (
Type == 3 && !DetermineForCompleteObject)
12200 llvm::APInt APEndOffset;
12201 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12205 if (LVal.InvalidBase)
12209 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
12215 const SubobjectDesignator &
Designator = LVal.Designator;
12227 llvm::APInt APEndOffset;
12228 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
12240 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
12246 int64_t ElemsRemaining;
12249 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
12250 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
12251 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
12253 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
12256 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
12266 EvalInfo &Info, uint64_t &Size) {
12273 SpeculativeEvaluationRAII SpeculativeEval(Info);
12274 IgnoreSideEffectsRAII Fold(Info);
12282 LVal.setFrom(Info.Ctx, RVal);
12290 if (LVal.getLValueOffset().isNegative()) {
12301 if (EndOffset <= LVal.getLValueOffset())
12304 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
12308bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12309 if (!IsConstantEvaluatedBuiltinCall(E))
12310 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12327 Info.FFDiag(E->
getArg(0));
12333 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
12334 "Bit widths must be the same");
12341bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
12342 unsigned BuiltinOp) {
12343 switch (BuiltinOp) {
12347 case Builtin::BI__builtin_dynamic_object_size:
12348 case Builtin::BI__builtin_object_size: {
12352 assert(
Type <= 3 &&
"unexpected type");
12363 switch (Info.EvalMode) {
12364 case EvalInfo::EM_ConstantExpression:
12365 case EvalInfo::EM_ConstantFold:
12366 case EvalInfo::EM_IgnoreSideEffects:
12369 case EvalInfo::EM_ConstantExpressionUnevaluated:
12374 llvm_unreachable(
"unexpected EvalMode");
12377 case Builtin::BI__builtin_os_log_format_buffer_size: {
12383 case Builtin::BI__builtin_is_aligned: {
12391 Ptr.setFrom(Info.Ctx, Src);
12397 assert(Alignment.isPowerOf2());
12410 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
12414 assert(Src.
isInt());
12415 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
12417 case Builtin::BI__builtin_align_up: {
12425 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
12426 Src.
getInt().isUnsigned());
12427 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12428 return Success(AlignedVal, E);
12430 case Builtin::BI__builtin_align_down: {
12439 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
12440 return Success(AlignedVal, E);
12443 case Builtin::BI__builtin_bitreverse8:
12444 case Builtin::BI__builtin_bitreverse16:
12445 case Builtin::BI__builtin_bitreverse32:
12446 case Builtin::BI__builtin_bitreverse64: {
12451 return Success(Val.reverseBits(), E);
12454 case Builtin::BI__builtin_bswap16:
12455 case Builtin::BI__builtin_bswap32:
12456 case Builtin::BI__builtin_bswap64: {
12461 return Success(Val.byteSwap(), E);
12464 case Builtin::BI__builtin_classify_type:
12467 case Builtin::BI__builtin_clrsb:
12468 case Builtin::BI__builtin_clrsbl:
12469 case Builtin::BI__builtin_clrsbll: {
12474 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
12477 case Builtin::BI__builtin_clz:
12478 case Builtin::BI__builtin_clzl:
12479 case Builtin::BI__builtin_clzll:
12480 case Builtin::BI__builtin_clzs:
12481 case Builtin::BI__builtin_clzg:
12482 case Builtin::BI__lzcnt16:
12483 case Builtin::BI__lzcnt:
12484 case Builtin::BI__lzcnt64: {
12489 std::optional<APSInt> Fallback;
12490 if (BuiltinOp == Builtin::BI__builtin_clzg && E->
getNumArgs() > 1) {
12494 Fallback = FallbackTemp;
12499 return Success(*Fallback, E);
12504 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
12505 BuiltinOp != Builtin::BI__lzcnt &&
12506 BuiltinOp != Builtin::BI__lzcnt64;
12508 if (ZeroIsUndefined)
12512 return Success(Val.countl_zero(), E);
12515 case Builtin::BI__builtin_constant_p: {
12525 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
12529 case Builtin::BI__builtin_is_constant_evaluated: {
12530 const auto *
Callee = Info.CurrentCall->getCallee();
12531 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
12532 (Info.CallStackDepth == 1 ||
12533 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
12534 Callee->getIdentifier() &&
12535 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
12537 if (Info.EvalStatus.Diag)
12538 Info.report((Info.CallStackDepth == 1)
12540 : Info.CurrentCall->getCallRange().getBegin(),
12541 diag::warn_is_constant_evaluated_always_true_constexpr)
12542 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
12543 :
"std::is_constant_evaluated");
12546 return Success(Info.InConstantContext, E);
12549 case Builtin::BI__builtin_ctz:
12550 case Builtin::BI__builtin_ctzl:
12551 case Builtin::BI__builtin_ctzll:
12552 case Builtin::BI__builtin_ctzs:
12553 case Builtin::BI__builtin_ctzg: {
12558 std::optional<APSInt> Fallback;
12559 if (BuiltinOp == Builtin::BI__builtin_ctzg && E->
getNumArgs() > 1) {
12563 Fallback = FallbackTemp;
12568 return Success(*Fallback, E);
12573 return Success(Val.countr_zero(), E);
12576 case Builtin::BI__builtin_eh_return_data_regno: {
12578 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
12582 case Builtin::BI__builtin_expect:
12583 case Builtin::BI__builtin_expect_with_probability:
12584 return Visit(E->
getArg(0));
12586 case Builtin::BI__builtin_ffs:
12587 case Builtin::BI__builtin_ffsl:
12588 case Builtin::BI__builtin_ffsll: {
12593 unsigned N = Val.countr_zero();
12594 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
12597 case Builtin::BI__builtin_fpclassify: {
12602 switch (Val.getCategory()) {
12603 case APFloat::fcNaN: Arg = 0;
break;
12604 case APFloat::fcInfinity: Arg = 1;
break;
12605 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
12606 case APFloat::fcZero: Arg = 4;
break;
12608 return Visit(E->
getArg(Arg));
12611 case Builtin::BI__builtin_isinf_sign: {
12614 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
12617 case Builtin::BI__builtin_isinf: {
12620 Success(Val.isInfinity() ? 1 : 0, E);
12623 case Builtin::BI__builtin_isfinite: {
12626 Success(Val.isFinite() ? 1 : 0, E);
12629 case Builtin::BI__builtin_isnan: {
12632 Success(Val.isNaN() ? 1 : 0, E);
12635 case Builtin::BI__builtin_isnormal: {
12638 Success(Val.isNormal() ? 1 : 0, E);
12641 case Builtin::BI__builtin_issubnormal: {
12644 Success(Val.isDenormal() ? 1 : 0, E);
12647 case Builtin::BI__builtin_iszero: {
12650 Success(Val.isZero() ? 1 : 0, E);
12653 case Builtin::BI__builtin_issignaling: {
12656 Success(Val.isSignaling() ? 1 : 0, E);
12659 case Builtin::BI__builtin_isfpclass: {
12663 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
12666 Success((Val.classify() & Test) ? 1 : 0, E);
12669 case Builtin::BI__builtin_parity:
12670 case Builtin::BI__builtin_parityl:
12671 case Builtin::BI__builtin_parityll: {
12676 return Success(Val.popcount() % 2, E);
12679 case Builtin::BI__builtin_popcount:
12680 case Builtin::BI__builtin_popcountl:
12681 case Builtin::BI__builtin_popcountll:
12682 case Builtin::BI__builtin_popcountg:
12683 case Builtin::BI__popcnt16:
12684 case Builtin::BI__popcnt:
12685 case Builtin::BI__popcnt64: {
12690 return Success(Val.popcount(), E);
12693 case Builtin::BI__builtin_rotateleft8:
12694 case Builtin::BI__builtin_rotateleft16:
12695 case Builtin::BI__builtin_rotateleft32:
12696 case Builtin::BI__builtin_rotateleft64:
12697 case Builtin::BI_rotl8:
12698 case Builtin::BI_rotl16:
12699 case Builtin::BI_rotl:
12700 case Builtin::BI_lrotl:
12701 case Builtin::BI_rotl64: {
12707 return Success(Val.rotl(Amt.urem(Val.getBitWidth())), E);
12710 case Builtin::BI__builtin_rotateright8:
12711 case Builtin::BI__builtin_rotateright16:
12712 case Builtin::BI__builtin_rotateright32:
12713 case Builtin::BI__builtin_rotateright64:
12714 case Builtin::BI_rotr8:
12715 case Builtin::BI_rotr16:
12716 case Builtin::BI_rotr:
12717 case Builtin::BI_lrotr:
12718 case Builtin::BI_rotr64: {
12724 return Success(Val.rotr(Amt.urem(Val.getBitWidth())), E);
12727 case Builtin::BIstrlen:
12728 case Builtin::BIwcslen:
12730 if (Info.getLangOpts().CPlusPlus11)
12731 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
12733 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12735 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12737 case Builtin::BI__builtin_strlen:
12738 case Builtin::BI__builtin_wcslen: {
12747 case Builtin::BIstrcmp:
12748 case Builtin::BIwcscmp:
12749 case Builtin::BIstrncmp:
12750 case Builtin::BIwcsncmp:
12751 case Builtin::BImemcmp:
12752 case Builtin::BIbcmp:
12753 case Builtin::BIwmemcmp:
12755 if (Info.getLangOpts().CPlusPlus11)
12756 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
12758 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str();
12760 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12762 case Builtin::BI__builtin_strcmp:
12763 case Builtin::BI__builtin_wcscmp:
12764 case Builtin::BI__builtin_strncmp:
12765 case Builtin::BI__builtin_wcsncmp:
12766 case Builtin::BI__builtin_memcmp:
12767 case Builtin::BI__builtin_bcmp:
12768 case Builtin::BI__builtin_wmemcmp: {
12769 LValue String1, String2;
12775 if (BuiltinOp != Builtin::BIstrcmp &&
12776 BuiltinOp != Builtin::BIwcscmp &&
12777 BuiltinOp != Builtin::BI__builtin_strcmp &&
12778 BuiltinOp != Builtin::BI__builtin_wcscmp) {
12782 MaxLength = N.getZExtValue();
12786 if (MaxLength == 0u)
12789 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
12790 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
12791 String1.Designator.Invalid || String2.Designator.Invalid)
12794 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
12795 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
12797 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
12798 BuiltinOp == Builtin::BIbcmp ||
12799 BuiltinOp == Builtin::BI__builtin_memcmp ||
12800 BuiltinOp == Builtin::BI__builtin_bcmp;
12802 assert(IsRawByte ||
12803 (Info.Ctx.hasSameUnqualifiedType(
12805 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
12812 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
12813 << (
"'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'").str()
12814 << CharTy1 << CharTy2;
12818 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
12821 Char1.
isInt() && Char2.isInt();
12823 const auto &AdvanceElems = [&] {
12829 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
12830 BuiltinOp != Builtin::BIwmemcmp &&
12831 BuiltinOp != Builtin::BI__builtin_memcmp &&
12832 BuiltinOp != Builtin::BI__builtin_bcmp &&
12833 BuiltinOp != Builtin::BI__builtin_wmemcmp);
12834 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
12835 BuiltinOp == Builtin::BIwcsncmp ||
12836 BuiltinOp == Builtin::BIwmemcmp ||
12837 BuiltinOp == Builtin::BI__builtin_wcscmp ||
12838 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
12839 BuiltinOp == Builtin::BI__builtin_wmemcmp;
12841 for (; MaxLength; --MaxLength) {
12843 if (!ReadCurElems(Char1, Char2))
12851 if (StopAtNull && !Char1.
getInt())
12853 assert(!(StopAtNull && !Char2.
getInt()));
12854 if (!AdvanceElems())
12861 case Builtin::BI__atomic_always_lock_free:
12862 case Builtin::BI__atomic_is_lock_free:
12863 case Builtin::BI__c11_atomic_is_lock_free: {
12879 if (
Size.isPowerOfTwo()) {
12881 unsigned InlineWidthBits =
12882 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
12883 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
12884 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
12895 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
12902 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
12905 case Builtin::BI__builtin_addcb:
12906 case Builtin::BI__builtin_addcs:
12907 case Builtin::BI__builtin_addc:
12908 case Builtin::BI__builtin_addcl:
12909 case Builtin::BI__builtin_addcll:
12910 case Builtin::BI__builtin_subcb:
12911 case Builtin::BI__builtin_subcs:
12912 case Builtin::BI__builtin_subc:
12913 case Builtin::BI__builtin_subcl:
12914 case Builtin::BI__builtin_subcll: {
12915 LValue CarryOutLValue;
12916 APSInt LHS, RHS, CarryIn, CarryOut, Result;
12927 bool FirstOverflowed =
false;
12928 bool SecondOverflowed =
false;
12929 switch (BuiltinOp) {
12931 llvm_unreachable(
"Invalid value for BuiltinOp");
12932 case Builtin::BI__builtin_addcb:
12933 case Builtin::BI__builtin_addcs:
12934 case Builtin::BI__builtin_addc:
12935 case Builtin::BI__builtin_addcl:
12936 case Builtin::BI__builtin_addcll:
12938 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
12940 case Builtin::BI__builtin_subcb:
12941 case Builtin::BI__builtin_subcs:
12942 case Builtin::BI__builtin_subc:
12943 case Builtin::BI__builtin_subcl:
12944 case Builtin::BI__builtin_subcll:
12946 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
12952 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
12958 case Builtin::BI__builtin_add_overflow:
12959 case Builtin::BI__builtin_sub_overflow:
12960 case Builtin::BI__builtin_mul_overflow:
12961 case Builtin::BI__builtin_sadd_overflow:
12962 case Builtin::BI__builtin_uadd_overflow:
12963 case Builtin::BI__builtin_uaddl_overflow:
12964 case Builtin::BI__builtin_uaddll_overflow:
12965 case Builtin::BI__builtin_usub_overflow:
12966 case Builtin::BI__builtin_usubl_overflow:
12967 case Builtin::BI__builtin_usubll_overflow:
12968 case Builtin::BI__builtin_umul_overflow:
12969 case Builtin::BI__builtin_umull_overflow:
12970 case Builtin::BI__builtin_umulll_overflow:
12971 case Builtin::BI__builtin_saddl_overflow:
12972 case Builtin::BI__builtin_saddll_overflow:
12973 case Builtin::BI__builtin_ssub_overflow:
12974 case Builtin::BI__builtin_ssubl_overflow:
12975 case Builtin::BI__builtin_ssubll_overflow:
12976 case Builtin::BI__builtin_smul_overflow:
12977 case Builtin::BI__builtin_smull_overflow:
12978 case Builtin::BI__builtin_smulll_overflow: {
12979 LValue ResultLValue;
12989 bool DidOverflow =
false;
12992 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
12993 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
12994 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
12995 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
12997 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
12999 uint64_t LHSSize = LHS.getBitWidth();
13000 uint64_t RHSSize = RHS.getBitWidth();
13001 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
13002 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
13008 if (IsSigned && !AllSigned)
13011 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
13012 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
13013 Result =
APSInt(MaxBits, !IsSigned);
13017 switch (BuiltinOp) {
13019 llvm_unreachable(
"Invalid value for BuiltinOp");
13020 case Builtin::BI__builtin_add_overflow:
13021 case Builtin::BI__builtin_sadd_overflow:
13022 case Builtin::BI__builtin_saddl_overflow:
13023 case Builtin::BI__builtin_saddll_overflow:
13024 case Builtin::BI__builtin_uadd_overflow:
13025 case Builtin::BI__builtin_uaddl_overflow:
13026 case Builtin::BI__builtin_uaddll_overflow:
13027 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
13028 : LHS.uadd_ov(RHS, DidOverflow);
13030 case Builtin::BI__builtin_sub_overflow:
13031 case Builtin::BI__builtin_ssub_overflow:
13032 case Builtin::BI__builtin_ssubl_overflow:
13033 case Builtin::BI__builtin_ssubll_overflow:
13034 case Builtin::BI__builtin_usub_overflow:
13035 case Builtin::BI__builtin_usubl_overflow:
13036 case Builtin::BI__builtin_usubll_overflow:
13037 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
13038 : LHS.usub_ov(RHS, DidOverflow);
13040 case Builtin::BI__builtin_mul_overflow:
13041 case Builtin::BI__builtin_smul_overflow:
13042 case Builtin::BI__builtin_smull_overflow:
13043 case Builtin::BI__builtin_smulll_overflow:
13044 case Builtin::BI__builtin_umul_overflow:
13045 case Builtin::BI__builtin_umull_overflow:
13046 case Builtin::BI__builtin_umulll_overflow:
13047 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
13048 : LHS.umul_ov(RHS, DidOverflow);
13054 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
13055 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
13056 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
13062 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
13065 if (!APSInt::isSameValue(Temp, Result))
13066 DidOverflow =
true;
13073 return Success(DidOverflow, E);
13081 const LValue &LV) {
13084 if (!LV.getLValueBase())
13089 if (!LV.getLValueDesignator().Invalid &&
13090 !LV.getLValueDesignator().isOnePastTheEnd())
13095 QualType Ty = getType(LV.getLValueBase());
13100 if (LV.getLValueDesignator().Invalid)
13106 return LV.getLValueOffset() == Size;
13116class DataRecursiveIntBinOpEvaluator {
13117 struct EvalResult {
13119 bool Failed =
false;
13121 EvalResult() =
default;
13123 void swap(EvalResult &RHS) {
13125 Failed = RHS.Failed;
13126 RHS.Failed =
false;
13132 EvalResult LHSResult;
13133 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
13136 Job(Job &&) =
default;
13138 void startSpeculativeEval(EvalInfo &Info) {
13139 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
13143 SpeculativeEvaluationRAII SpecEvalRAII;
13148 IntExprEvaluator &IntEval;
13153 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
13154 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
13169 EvalResult PrevResult;
13170 while (!Queue.empty())
13171 process(PrevResult);
13173 if (PrevResult.Failed)
return false;
13175 FinalResult.
swap(PrevResult.Val);
13181 return IntEval.Success(
Value, E, Result);
13184 return IntEval.Success(
Value, E, Result);
13187 return IntEval.Error(E);
13190 return IntEval.Error(E, D);
13194 return Info.CCEDiag(E, D);
13198 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
13199 bool &SuppressRHSDiags);
13201 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13204 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
13205 Result.Failed = !
Evaluate(Result.Val, Info, E);
13210 void process(EvalResult &Result);
13212 void enqueue(
const Expr *E) {
13214 Queue.resize(Queue.size()+1);
13215 Queue.back().E = E;
13216 Queue.back().Kind = Job::AnyExprKind;
13222bool DataRecursiveIntBinOpEvaluator::
13223 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
13224 bool &SuppressRHSDiags) {
13227 if (LHSResult.Failed)
13228 return Info.noteSideEffect();
13237 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
13238 Success(LHSAsBool, E, LHSResult.Val);
13242 LHSResult.Failed =
true;
13246 if (!Info.noteSideEffect())
13252 SuppressRHSDiags =
true;
13261 if (LHSResult.Failed && !Info.noteFailure())
13272 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
13274 uint64_t Offset64 = Offset.getQuantity();
13275 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
13277 : Offset64 + Index64);
13280bool DataRecursiveIntBinOpEvaluator::
13281 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
13284 if (RHSResult.Failed)
13286 Result = RHSResult.Val;
13291 bool lhsResult, rhsResult;
13298 return Success(lhsResult || rhsResult, E, Result);
13300 return Success(lhsResult && rhsResult, E, Result);
13306 if (rhsResult == (E->
getOpcode() == BO_LOr))
13307 return Success(rhsResult, E, Result);
13317 if (LHSResult.Failed || RHSResult.Failed)
13320 const APValue &LHSVal = LHSResult.Val;
13321 const APValue &RHSVal = RHSResult.Val;
13345 if (!LHSExpr || !RHSExpr)
13347 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
13348 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
13349 if (!LHSAddrExpr || !RHSAddrExpr)
13355 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
13374void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
13375 Job &job = Queue.back();
13377 switch (job.Kind) {
13378 case Job::AnyExprKind: {
13379 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
13380 if (shouldEnqueue(Bop)) {
13381 job.Kind = Job::BinOpKind;
13382 enqueue(Bop->getLHS());
13387 EvaluateExpr(job.E, Result);
13392 case Job::BinOpKind: {
13394 bool SuppressRHSDiags =
false;
13395 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
13399 if (SuppressRHSDiags)
13400 job.startSpeculativeEval(Info);
13401 job.LHSResult.swap(Result);
13402 job.Kind = Job::BinOpVisitedLHSKind;
13407 case Job::BinOpVisitedLHSKind: {
13411 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
13417 llvm_unreachable(
"Invalid Job::Kind!");
13421enum class CmpResult {
13430template <
class SuccessCB,
class AfterCB>
13433 SuccessCB &&
Success, AfterCB &&DoAfter) {
13438 "unsupported binary expression evaluation");
13439 auto Error = [&](
const Expr *E) {
13440 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
13454 if (!LHSOK && !Info.noteFailure())
13459 return Success(CmpResult::Less, E);
13461 return Success(CmpResult::Greater, E);
13462 return Success(CmpResult::Equal, E);
13466 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
13467 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
13470 if (!LHSOK && !Info.noteFailure())
13475 return Success(CmpResult::Less, E);
13477 return Success(CmpResult::Greater, E);
13478 return Success(CmpResult::Equal, E);
13482 ComplexValue LHS, RHS;
13491 LHS.makeComplexFloat();
13492 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
13497 if (!LHSOK && !Info.noteFailure())
13503 RHS.makeComplexFloat();
13504 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
13508 if (LHS.isComplexFloat()) {
13509 APFloat::cmpResult CR_r =
13510 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
13511 APFloat::cmpResult CR_i =
13512 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
13513 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
13514 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
13516 assert(IsEquality &&
"invalid complex comparison");
13517 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
13518 LHS.getComplexIntImag() == RHS.getComplexIntImag();
13519 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
13525 APFloat RHS(0.0), LHS(0.0);
13528 if (!LHSOK && !Info.noteFailure())
13535 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
13536 if (!Info.InConstantContext &&
13537 APFloatCmpResult == APFloat::cmpUnordered &&
13540 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
13543 auto GetCmpRes = [&]() {
13544 switch (APFloatCmpResult) {
13545 case APFloat::cmpEqual:
13546 return CmpResult::Equal;
13547 case APFloat::cmpLessThan:
13548 return CmpResult::Less;
13549 case APFloat::cmpGreaterThan:
13550 return CmpResult::Greater;
13551 case APFloat::cmpUnordered:
13552 return CmpResult::Unordered;
13554 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
13556 return Success(GetCmpRes(), E);
13560 LValue LHSValue, RHSValue;
13563 if (!LHSOK && !Info.noteFailure())
13572 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
13573 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
13574 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
13575 Info.FFDiag(E, DiagID)
13582 return DiagComparison(
13583 diag::note_constexpr_pointer_comparison_unspecified);
13589 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
13590 (!RHSValue.Base && !RHSValue.Offset.isZero()))
13591 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
13598 LHSValue.Base && RHSValue.Base)
13599 return DiagComparison(diag::note_constexpr_literal_comparison);
13603 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
13607 if (LHSValue.Base && LHSValue.Offset.isZero() &&
13609 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13611 if (RHSValue.Base && RHSValue.Offset.isZero() &&
13613 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
13619 return DiagComparison(
13620 diag::note_constexpr_pointer_comparison_zero_sized);
13621 return Success(CmpResult::Unequal, E);
13624 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
13625 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
13627 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
13628 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
13638 Info.CCEDiag(E, diag::note_constexpr_void_comparison);
13648 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
13649 bool WasArrayIndex;
13651 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
13658 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
13659 Mismatch < RHSDesignator.Entries.size()) {
13660 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
13661 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
13663 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
13665 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
13666 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
13669 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
13670 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
13675 diag::note_constexpr_pointer_comparison_differing_access)
13683 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
13686 assert(PtrSize <= 64 &&
"Unexpected pointer width");
13687 uint64_t Mask = ~0ULL >> (64 - PtrSize);
13688 CompareLHS &= Mask;
13689 CompareRHS &= Mask;
13694 if (!LHSValue.Base.isNull() && IsRelational) {
13695 QualType BaseTy = getType(LHSValue.Base);
13698 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
13699 uint64_t OffsetLimit = Size.getQuantity();
13700 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
13704 if (CompareLHS < CompareRHS)
13705 return Success(CmpResult::Less, E);
13706 if (CompareLHS > CompareRHS)
13707 return Success(CmpResult::Greater, E);
13708 return Success(CmpResult::Equal, E);
13712 assert(IsEquality &&
"unexpected member pointer operation");
13715 MemberPtr LHSValue, RHSValue;
13718 if (!LHSOK && !Info.noteFailure())
13726 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
13727 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
13728 << LHSValue.getDecl();
13731 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
13732 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
13733 << RHSValue.getDecl();
13740 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
13741 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
13742 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
13747 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
13748 if (MD->isVirtual())
13749 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
13750 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
13751 if (MD->isVirtual())
13752 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
13758 bool Equal = LHSValue == RHSValue;
13759 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
13764 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
13772 return Success(CmpResult::Equal, E);
13785 case CmpResult::Unequal:
13786 llvm_unreachable(
"should never produce Unequal for three-way comparison");
13787 case CmpResult::Less:
13788 CCR = ComparisonCategoryResult::Less;
13790 case CmpResult::Equal:
13791 CCR = ComparisonCategoryResult::Equal;
13793 case CmpResult::Greater:
13794 CCR = ComparisonCategoryResult::Greater;
13796 case CmpResult::Unordered:
13797 CCR = ComparisonCategoryResult::Unordered;
13811 ConstantExprKind::Normal);
13814 return ExprEvaluatorBaseTy::VisitBinCmp(E);
13818bool RecordExprEvaluator::VisitCXXParenListInitExpr(
13820 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
13823bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
13828 if (!Info.noteFailure())
13832 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
13833 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
13837 "DataRecursiveIntBinOpEvaluator should have handled integral types");
13843 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
13844 "should only produce Unequal for equality comparisons");
13845 bool IsEqual = CR == CmpResult::Equal,
13846 IsLess = CR == CmpResult::Less,
13847 IsGreater = CR == CmpResult::Greater;
13851 llvm_unreachable(
"unsupported binary operator");
13854 return Success(IsEqual == (Op == BO_EQ), E);
13858 return Success(IsGreater, E);
13860 return Success(IsEqual || IsLess, E);
13862 return Success(IsEqual || IsGreater, E);
13866 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
13875 LValue LHSValue, RHSValue;
13878 if (!LHSOK && !Info.noteFailure())
13888 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
13890 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
13891 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
13892 if (!LHSExpr || !RHSExpr)
13894 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
13895 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
13896 if (!LHSAddrExpr || !RHSAddrExpr)
13904 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
13905 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
13907 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
13908 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
13914 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
13917 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
13929 if (ElementSize.
isZero()) {
13930 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
13947 APSInt TrueResult = (LHS - RHS) / ElemSize;
13948 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
13950 if (Result.extend(65) != TrueResult &&
13956 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
13961bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
13964 case UETT_PreferredAlignOf:
13965 case UETT_AlignOf: {
13974 case UETT_VecStep: {
13990 case UETT_DataSizeOf:
13991 case UETT_SizeOf: {
14000 E->
getKind() == UETT_DataSizeOf ? SizeOfType::DataSizeOf
14001 : SizeOfType::SizeOf)) {
14006 case UETT_OpenMPRequiredSimdAlign:
14009 Info.Ctx.toCharUnitsFromBits(
14013 case UETT_VectorElements: {
14021 if (Info.InConstantContext)
14022 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
14029 llvm_unreachable(
"unknown expr/type trait");
14032bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
14038 for (
unsigned i = 0; i != n; ++i) {
14046 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
14050 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
14051 Result += IdxResult.getSExtValue() * ElementSize;
14064 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
14071 llvm_unreachable(
"dependent __builtin_offsetof");
14087 CurrentType = BaseSpec->
getType();
14101bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
14117 if (!Result.isInt())
return Error(E);
14120 if (Info.checkingForUndefinedBehavior())
14121 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14122 diag::warn_integer_constant_overflow)
14136 if (!Result.isInt())
return Error(E);
14137 return Success(~Result.getInt(), E);
14150bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14156 case CK_BaseToDerived:
14157 case CK_DerivedToBase:
14158 case CK_UncheckedDerivedToBase:
14161 case CK_ArrayToPointerDecay:
14162 case CK_FunctionToPointerDecay:
14163 case CK_NullToPointer:
14164 case CK_NullToMemberPointer:
14165 case CK_BaseToDerivedMemberPointer:
14166 case CK_DerivedToBaseMemberPointer:
14167 case CK_ReinterpretMemberPointer:
14168 case CK_ConstructorConversion:
14169 case CK_IntegralToPointer:
14171 case CK_VectorSplat:
14172 case CK_IntegralToFloating:
14173 case CK_FloatingCast:
14174 case CK_CPointerToObjCPointerCast:
14175 case CK_BlockPointerToObjCPointerCast:
14176 case CK_AnyPointerToBlockPointerCast:
14177 case CK_ObjCObjectLValueCast:
14178 case CK_FloatingRealToComplex:
14179 case CK_FloatingComplexToReal:
14180 case CK_FloatingComplexCast:
14181 case CK_FloatingComplexToIntegralComplex:
14182 case CK_IntegralRealToComplex:
14183 case CK_IntegralComplexCast:
14184 case CK_IntegralComplexToFloatingComplex:
14185 case CK_BuiltinFnToFnPtr:
14186 case CK_ZeroToOCLOpaqueType:
14187 case CK_NonAtomicToAtomic:
14188 case CK_AddressSpaceConversion:
14189 case CK_IntToOCLSampler:
14190 case CK_FloatingToFixedPoint:
14191 case CK_FixedPointToFloating:
14192 case CK_FixedPointCast:
14193 case CK_IntegralToFixedPoint:
14194 case CK_MatrixCast:
14195 case CK_HLSLVectorTruncation:
14196 llvm_unreachable(
"invalid cast kind for integral value");
14200 case CK_LValueBitCast:
14201 case CK_ARCProduceObject:
14202 case CK_ARCConsumeObject:
14203 case CK_ARCReclaimReturnedObject:
14204 case CK_ARCExtendBlockObject:
14205 case CK_CopyAndAutoreleaseBlockObject:
14208 case CK_UserDefinedConversion:
14209 case CK_LValueToRValue:
14210 case CK_AtomicToNonAtomic:
14212 case CK_LValueToRValueBitCast:
14213 case CK_HLSLArrayRValue:
14214 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14216 case CK_MemberPointerToBoolean:
14217 case CK_PointerToBoolean:
14218 case CK_IntegralToBoolean:
14219 case CK_FloatingToBoolean:
14220 case CK_BooleanToSignedIntegral:
14221 case CK_FloatingComplexToBoolean:
14222 case CK_IntegralComplexToBoolean: {
14227 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
14229 return Success(IntResult, E);
14232 case CK_FixedPointToIntegral: {
14233 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
14237 llvm::APSInt Result = Src.convertToInt(
14238 Info.Ctx.getIntWidth(DestType),
14245 case CK_FixedPointToBoolean: {
14248 if (!
Evaluate(Val, Info, SubExpr))
14253 case CK_IntegralCast: {
14254 if (!Visit(SubExpr))
14257 if (!Result.isInt()) {
14263 if (Result.isAddrLabelDiff())
14264 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
14266 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
14269 if (Info.Ctx.getLangOpts().CPlusPlus && Info.InConstantContext &&
14270 Info.EvalMode == EvalInfo::EM_ConstantExpression &&
14273 bool ConstexprVar =
true;
14280 if (
const auto *VD = dyn_cast_or_null<VarDecl>(
14281 Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()))
14304 (
Max.slt(Result.getInt().getSExtValue()) ||
14305 Min.sgt(Result.getInt().getSExtValue())))
14306 Info.Ctx.getDiagnostics().Report(
14307 E->
getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range)
14308 << llvm::toString(Result.getInt(), 10) <<
Min.getSExtValue()
14309 <<
Max.getSExtValue() << ED;
14311 Max.ult(Result.getInt().getZExtValue()))
14312 Info.Ctx.getDiagnostics().Report(
14313 E->
getExprLoc(), diag::warn_constexpr_unscoped_enum_out_of_range)
14314 << llvm::toString(Result.getInt(), 10) <<
Min.getZExtValue()
14315 <<
Max.getZExtValue() << ED;
14320 Result.getInt()), E);
14323 case CK_PointerToIntegral: {
14324 CCEDiag(E, diag::note_constexpr_invalid_cast)
14325 << 2 << Info.Ctx.getLangOpts().CPlusPlus << E->
getSourceRange();
14331 if (LV.getLValueBase()) {
14336 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
14339 LV.Designator.setInvalid();
14340 LV.moveInto(Result);
14347 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
14348 llvm_unreachable(
"Can't cast this!");
14353 case CK_IntegralComplexToReal: {
14357 return Success(
C.getComplexIntReal(), E);
14360 case CK_FloatingToIntegral: {
14372 llvm_unreachable(
"unknown cast resulting in integral value");
14375bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
14380 if (!LV.isComplexInt())
14382 return Success(LV.getComplexIntReal(), E);
14388bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
14393 if (!LV.isComplexInt())
14395 return Success(LV.getComplexIntImag(), E);
14402bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
14406bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
14410bool IntExprEvaluator::VisitConceptSpecializationExpr(
14415bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
14419bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
14429 if (!Result.isFixedPoint())
14432 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
14446bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14450 "Expected destination type to be a fixed point type");
14451 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
14454 case CK_FixedPointCast: {
14455 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
14459 APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
14461 if (Info.checkingForUndefinedBehavior())
14462 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14463 diag::warn_fixedpoint_constant_overflow)
14464 << Result.toString() << E->
getType();
14470 case CK_IntegralToFixedPoint: {
14476 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
14477 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14480 if (Info.checkingForUndefinedBehavior())
14481 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14482 diag::warn_fixedpoint_constant_overflow)
14483 << IntResult.toString() << E->
getType();
14488 return Success(IntResult, E);
14490 case CK_FloatingToFixedPoint: {
14496 APFixedPoint Result = APFixedPoint::getFromFloatValue(
14497 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
14500 if (Info.checkingForUndefinedBehavior())
14501 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14502 diag::warn_fixedpoint_constant_overflow)
14503 << Result.toString() << E->
getType();
14511 case CK_LValueToRValue:
14512 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14518bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
14520 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
14524 FixedPointSemantics ResultFXSema =
14525 Info.Ctx.getFixedPointSemantics(E->
getType());
14527 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
14530 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
14534 bool OpOverflow =
false, ConversionOverflow =
false;
14535 APFixedPoint Result(LHSFX.getSemantics());
14538 Result = LHSFX.
add(RHSFX, &OpOverflow)
14539 .convert(ResultFXSema, &ConversionOverflow);
14543 Result = LHSFX.sub(RHSFX, &OpOverflow)
14544 .convert(ResultFXSema, &ConversionOverflow);
14548 Result = LHSFX.mul(RHSFX, &OpOverflow)
14549 .convert(ResultFXSema, &ConversionOverflow);
14553 if (RHSFX.getValue() == 0) {
14554 Info.FFDiag(E, diag::note_expr_divide_by_zero);
14557 Result = LHSFX.div(RHSFX, &OpOverflow)
14558 .convert(ResultFXSema, &ConversionOverflow);
14563 FixedPointSemantics LHSSema = LHSFX.getSemantics();
14564 llvm::APSInt RHSVal = RHSFX.getValue();
14567 LHSSema.getWidth() - (
unsigned)LHSSema.hasUnsignedPadding();
14568 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
14572 if (RHSVal.isNegative())
14573 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
14574 else if (Amt != RHSVal)
14575 Info.CCEDiag(E, diag::note_constexpr_large_shift)
14576 << RHSVal << E->
getType() << ShiftBW;
14579 Result = LHSFX.shl(Amt, &OpOverflow);
14581 Result = LHSFX.shr(Amt, &OpOverflow);
14587 if (OpOverflow || ConversionOverflow) {
14588 if (Info.checkingForUndefinedBehavior())
14589 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
14590 diag::warn_fixedpoint_constant_overflow)
14591 << Result.toString() << E->
getType();
14603class FloatExprEvaluator
14604 :
public ExprEvaluatorBase<FloatExprEvaluator> {
14607 FloatExprEvaluator(EvalInfo &info, APFloat &result)
14608 : ExprEvaluatorBaseTy(info), Result(result) {}
14611 Result =
V.getFloat();
14615 bool ZeroInitialization(
const Expr *E) {
14616 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
14620 bool VisitCallExpr(
const CallExpr *E);
14625 bool VisitCastExpr(
const CastExpr *E);
14637 return FloatExprEvaluator(Info, Result).Visit(E);
14644 llvm::APFloat &Result) {
14646 if (!S)
return false;
14653 if (S->getString().empty())
14654 fill = llvm::APInt(32, 0);
14655 else if (S->getString().getAsInteger(0, fill))
14660 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14662 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14670 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
14672 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
14678bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
14679 if (!IsConstantEvaluatedBuiltinCall(E))
14680 return ExprEvaluatorBaseTy::VisitCallExpr(E);
14686 case Builtin::BI__builtin_huge_val:
14687 case Builtin::BI__builtin_huge_valf:
14688 case Builtin::BI__builtin_huge_vall:
14689 case Builtin::BI__builtin_huge_valf16:
14690 case Builtin::BI__builtin_huge_valf128:
14691 case Builtin::BI__builtin_inf:
14692 case Builtin::BI__builtin_inff:
14693 case Builtin::BI__builtin_infl:
14694 case Builtin::BI__builtin_inff16:
14695 case Builtin::BI__builtin_inff128: {
14696 const llvm::fltSemantics &Sem =
14697 Info.Ctx.getFloatTypeSemantics(E->
getType());
14698 Result = llvm::APFloat::getInf(Sem);
14702 case Builtin::BI__builtin_nans:
14703 case Builtin::BI__builtin_nansf:
14704 case Builtin::BI__builtin_nansl:
14705 case Builtin::BI__builtin_nansf16:
14706 case Builtin::BI__builtin_nansf128:
14712 case Builtin::BI__builtin_nan:
14713 case Builtin::BI__builtin_nanf:
14714 case Builtin::BI__builtin_nanl:
14715 case Builtin::BI__builtin_nanf16:
14716 case Builtin::BI__builtin_nanf128:
14724 case Builtin::BI__builtin_fabs:
14725 case Builtin::BI__builtin_fabsf:
14726 case Builtin::BI__builtin_fabsl:
14727 case Builtin::BI__builtin_fabsf128:
14736 if (Result.isNegative())
14737 Result.changeSign();
14740 case Builtin::BI__arithmetic_fence:
14747 case Builtin::BI__builtin_copysign:
14748 case Builtin::BI__builtin_copysignf:
14749 case Builtin::BI__builtin_copysignl:
14750 case Builtin::BI__builtin_copysignf128: {
14755 Result.copySign(RHS);
14759 case Builtin::BI__builtin_fmax:
14760 case Builtin::BI__builtin_fmaxf:
14761 case Builtin::BI__builtin_fmaxl:
14762 case Builtin::BI__builtin_fmaxf16:
14763 case Builtin::BI__builtin_fmaxf128: {
14770 if (Result.isZero() && RHS.isZero() && Result.isNegative())
14772 else if (Result.isNaN() || RHS > Result)
14777 case Builtin::BI__builtin_fmin:
14778 case Builtin::BI__builtin_fminf:
14779 case Builtin::BI__builtin_fminl:
14780 case Builtin::BI__builtin_fminf16:
14781 case Builtin::BI__builtin_fminf128: {
14788 if (Result.isZero() && RHS.isZero() && RHS.isNegative())
14790 else if (Result.isNaN() || RHS < Result)
14797bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
14802 Result = CV.FloatReal;
14809bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
14814 Result = CV.FloatImag;
14819 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
14820 Result = llvm::APFloat::getZero(Sem);
14824bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
14826 default:
return Error(E);
14835 Result.changeSign();
14840bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
14842 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
14846 if (!LHSOK && !Info.noteFailure())
14852bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
14857bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14862 return ExprEvaluatorBaseTy::VisitCastExpr(E);
14864 case CK_IntegralToFloating: {
14867 Info.Ctx.getLangOpts());
14870 IntResult, E->
getType(), Result);
14873 case CK_FixedPointToFloating: {
14874 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
14878 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
14882 case CK_FloatingCast: {
14883 if (!Visit(SubExpr))
14889 case CK_FloatingComplexToReal: {
14893 Result =
V.getComplexFloatReal();
14904class ComplexExprEvaluator
14905 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
14906 ComplexValue &Result;
14909 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
14910 : ExprEvaluatorBaseTy(info), Result(Result) {}
14917 bool ZeroInitialization(
const Expr *E);
14924 bool VisitCastExpr(
const CastExpr *E);
14928 bool VisitCallExpr(
const CallExpr *E);
14936 return ComplexExprEvaluator(Info, Result).Visit(E);
14939bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
14942 Result.makeComplexFloat();
14943 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
14944 Result.FloatReal =
Zero;
14945 Result.FloatImag =
Zero;
14947 Result.makeComplexInt();
14948 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
14949 Result.IntReal =
Zero;
14950 Result.IntImag =
Zero;
14955bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
14959 Result.makeComplexFloat();
14960 APFloat &Imag = Result.FloatImag;
14964 Result.FloatReal =
APFloat(Imag.getSemantics());
14968 "Unexpected imaginary literal.");
14970 Result.makeComplexInt();
14971 APSInt &Imag = Result.IntImag;
14975 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
14980bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
14984 case CK_BaseToDerived:
14985 case CK_DerivedToBase:
14986 case CK_UncheckedDerivedToBase:
14989 case CK_ArrayToPointerDecay:
14990 case CK_FunctionToPointerDecay:
14991 case CK_NullToPointer:
14992 case CK_NullToMemberPointer:
14993 case CK_BaseToDerivedMemberPointer:
14994 case CK_DerivedToBaseMemberPointer:
14995 case CK_MemberPointerToBoolean:
14996 case CK_ReinterpretMemberPointer:
14997 case CK_ConstructorConversion:
14998 case CK_IntegralToPointer:
14999 case CK_PointerToIntegral:
15000 case CK_PointerToBoolean:
15002 case CK_VectorSplat:
15003 case CK_IntegralCast:
15004 case CK_BooleanToSignedIntegral:
15005 case CK_IntegralToBoolean:
15006 case CK_IntegralToFloating:
15007 case CK_FloatingToIntegral:
15008 case CK_FloatingToBoolean:
15009 case CK_FloatingCast:
15010 case CK_CPointerToObjCPointerCast:
15011 case CK_BlockPointerToObjCPointerCast:
15012 case CK_AnyPointerToBlockPointerCast:
15013 case CK_ObjCObjectLValueCast:
15014 case CK_FloatingComplexToReal:
15015 case CK_FloatingComplexToBoolean:
15016 case CK_IntegralComplexToReal:
15017 case CK_IntegralComplexToBoolean:
15018 case CK_ARCProduceObject:
15019 case CK_ARCConsumeObject:
15020 case CK_ARCReclaimReturnedObject:
15021 case CK_ARCExtendBlockObject:
15022 case CK_CopyAndAutoreleaseBlockObject:
15023 case CK_BuiltinFnToFnPtr:
15024 case CK_ZeroToOCLOpaqueType:
15025 case CK_NonAtomicToAtomic:
15026 case CK_AddressSpaceConversion:
15027 case CK_IntToOCLSampler:
15028 case CK_FloatingToFixedPoint:
15029 case CK_FixedPointToFloating:
15030 case CK_FixedPointCast:
15031 case CK_FixedPointToBoolean:
15032 case CK_FixedPointToIntegral:
15033 case CK_IntegralToFixedPoint:
15034 case CK_MatrixCast:
15035 case CK_HLSLVectorTruncation:
15036 llvm_unreachable(
"invalid cast kind for complex value");
15038 case CK_LValueToRValue:
15039 case CK_AtomicToNonAtomic:
15041 case CK_LValueToRValueBitCast:
15042 case CK_HLSLArrayRValue:
15043 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15046 case CK_LValueBitCast:
15047 case CK_UserDefinedConversion:
15050 case CK_FloatingRealToComplex: {
15051 APFloat &Real = Result.FloatReal;
15055 Result.makeComplexFloat();
15056 Result.FloatImag =
APFloat(Real.getSemantics());
15060 case CK_FloatingComplexCast: {
15072 case CK_FloatingComplexToIntegralComplex: {
15079 Result.makeComplexInt();
15081 To, Result.IntReal) &&
15083 To, Result.IntImag);
15086 case CK_IntegralRealToComplex: {
15087 APSInt &Real = Result.IntReal;
15091 Result.makeComplexInt();
15092 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
15096 case CK_IntegralComplexCast: {
15109 case CK_IntegralComplexToFloatingComplex: {
15114 Info.Ctx.getLangOpts());
15118 Result.makeComplexFloat();
15120 To, Result.FloatReal) &&
15122 To, Result.FloatImag);
15126 llvm_unreachable(
"unknown cast resulting in complex value");
15129bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
15131 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
15135 bool LHSReal =
false, RHSReal =
false;
15140 APFloat &Real = Result.FloatReal;
15143 Result.makeComplexFloat();
15144 Result.FloatImag =
APFloat(Real.getSemantics());
15147 LHSOK = Visit(E->
getLHS());
15149 if (!LHSOK && !Info.noteFailure())
15155 APFloat &Real = RHS.FloatReal;
15158 RHS.makeComplexFloat();
15159 RHS.FloatImag =
APFloat(Real.getSemantics());
15163 assert(!(LHSReal && RHSReal) &&
15164 "Cannot have both operands of a complex operation be real.");
15166 default:
return Error(E);
15168 if (Result.isComplexFloat()) {
15169 Result.getComplexFloatReal().
add(RHS.getComplexFloatReal(),
15170 APFloat::rmNearestTiesToEven);
15172 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15174 Result.getComplexFloatImag().
add(RHS.getComplexFloatImag(),
15175 APFloat::rmNearestTiesToEven);
15177 Result.getComplexIntReal() += RHS.getComplexIntReal();
15178 Result.getComplexIntImag() += RHS.getComplexIntImag();
15182 if (Result.isComplexFloat()) {
15183 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
15184 APFloat::rmNearestTiesToEven);
15186 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
15187 Result.getComplexFloatImag().changeSign();
15188 }
else if (!RHSReal) {
15189 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
15190 APFloat::rmNearestTiesToEven);
15193 Result.getComplexIntReal() -= RHS.getComplexIntReal();
15194 Result.getComplexIntImag() -= RHS.getComplexIntImag();
15198 if (Result.isComplexFloat()) {
15203 ComplexValue LHS = Result;
15204 APFloat &A = LHS.getComplexFloatReal();
15205 APFloat &B = LHS.getComplexFloatImag();
15206 APFloat &
C = RHS.getComplexFloatReal();
15207 APFloat &D = RHS.getComplexFloatImag();
15208 APFloat &ResR = Result.getComplexFloatReal();
15209 APFloat &ResI = Result.getComplexFloatImag();
15211 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
15214 }
else if (RHSReal) {
15226 if (ResR.isNaN() && ResI.isNaN()) {
15227 bool Recalc =
false;
15228 if (A.isInfinity() || B.isInfinity()) {
15229 A = APFloat::copySign(
15230 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
15231 B = APFloat::copySign(
15232 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
15234 C = APFloat::copySign(
APFloat(
C.getSemantics()),
C);
15236 D = APFloat::copySign(
APFloat(D.getSemantics()), D);
15239 if (
C.isInfinity() || D.isInfinity()) {
15240 C = APFloat::copySign(
15241 APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
C);
15242 D = APFloat::copySign(
15243 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
15245 A = APFloat::copySign(
APFloat(A.getSemantics()), A);
15247 B = APFloat::copySign(
APFloat(B.getSemantics()), B);
15250 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
15251 AD.isInfinity() || BC.isInfinity())) {
15253 A = APFloat::copySign(
APFloat(A.getSemantics()), A);
15255 B = APFloat::copySign(
APFloat(B.getSemantics()), B);
15257 C = APFloat::copySign(
APFloat(
C.getSemantics()),
C);
15259 D = APFloat::copySign(
APFloat(D.getSemantics()), D);
15263 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
15264 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
15269 ComplexValue LHS = Result;
15270 Result.getComplexIntReal() =
15271 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
15272 LHS.getComplexIntImag() * RHS.getComplexIntImag());
15273 Result.getComplexIntImag() =
15274 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
15275 LHS.getComplexIntImag() * RHS.getComplexIntReal());
15279 if (Result.isComplexFloat()) {
15284 ComplexValue LHS = Result;
15285 APFloat &A = LHS.getComplexFloatReal();
15286 APFloat &B = LHS.getComplexFloatImag();
15287 APFloat &
C = RHS.getComplexFloatReal();
15288 APFloat &D = RHS.getComplexFloatImag();
15289 APFloat &ResR = Result.getComplexFloatReal();
15290 APFloat &ResI = Result.getComplexFloatImag();
15297 B = APFloat::getZero(A.getSemantics());
15301 if (MaxCD.isFinite()) {
15302 DenomLogB =
ilogb(MaxCD);
15303 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
15304 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
15307 ResR =
scalbn((A *
C + B * D) / Denom, -DenomLogB,
15308 APFloat::rmNearestTiesToEven);
15309 ResI =
scalbn((B *
C - A * D) / Denom, -DenomLogB,
15310 APFloat::rmNearestTiesToEven);
15311 if (ResR.isNaN() && ResI.isNaN()) {
15312 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
15313 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
15314 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
15315 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
15317 A = APFloat::copySign(
15318 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
15319 B = APFloat::copySign(
15320 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
15321 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
15322 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
15323 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
15324 C = APFloat::copySign(
15325 APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
C);
15326 D = APFloat::copySign(
15327 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
15328 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
15329 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
15334 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
15335 return Error(E, diag::note_expr_divide_by_zero);
15337 ComplexValue LHS = Result;
15338 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
15339 RHS.getComplexIntImag() * RHS.getComplexIntImag();
15340 Result.getComplexIntReal() =
15341 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
15342 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
15343 Result.getComplexIntImag() =
15344 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
15345 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
15353bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
15367 if (Result.isComplexFloat()) {
15368 Result.getComplexFloatReal().changeSign();
15369 Result.getComplexFloatImag().changeSign();
15372 Result.getComplexIntReal() = -Result.getComplexIntReal();
15373 Result.getComplexIntImag() = -Result.getComplexIntImag();
15377 if (Result.isComplexFloat())
15378 Result.getComplexFloatImag().changeSign();
15380 Result.getComplexIntImag() = -Result.getComplexIntImag();
15385bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15388 Result.makeComplexFloat();
15394 Result.makeComplexInt();
15402 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
15405bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
15406 if (!IsConstantEvaluatedBuiltinCall(E))
15407 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15410 case Builtin::BI__builtin_complex:
15411 Result.makeComplexFloat();
15429class AtomicExprEvaluator :
15430 public ExprEvaluatorBase<AtomicExprEvaluator> {
15431 const LValue *
This;
15434 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
15435 : ExprEvaluatorBaseTy(Info),
This(
This), Result(Result) {}
15442 bool ZeroInitialization(
const Expr *E) {
15451 bool VisitCastExpr(
const CastExpr *E) {
15454 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15455 case CK_NullToPointer:
15457 return ZeroInitialization(E);
15458 case CK_NonAtomicToAtomic:
15460 :
Evaluate(Result, Info, E->getSubExpr());
15470 return AtomicExprEvaluator(Info, This, Result).Visit(E);
15479class VoidExprEvaluator
15480 :
public ExprEvaluatorBase<VoidExprEvaluator> {
15482 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
15486 bool ZeroInitialization(
const Expr *E) {
return true; }
15488 bool VisitCastExpr(
const CastExpr *E) {
15491 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15498 bool VisitCallExpr(
const CallExpr *E) {
15499 if (!IsConstantEvaluatedBuiltinCall(E))
15500 return ExprEvaluatorBaseTy::VisitCallExpr(E);
15503 case Builtin::BI__assume:
15504 case Builtin::BI__builtin_assume:
15508 case Builtin::BI__builtin_operator_delete:
15520bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
15522 if (Info.SpeculativeEvaluationDepth)
15527 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
15528 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
15537 if (
Pointer.Designator.Invalid)
15541 if (
Pointer.isNullPointer()) {
15545 if (!Info.getLangOpts().CPlusPlus20)
15546 Info.CCEDiag(E, diag::note_constexpr_new);
15560 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
15569 if (VirtualDelete &&
15571 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
15572 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
15578 (*Alloc)->Value, AllocType))
15586 Info.FFDiag(E, diag::note_constexpr_double_delete);
15596 return VoidExprEvaluator(Info).Visit(E);
15612 LV.moveInto(Result);
15617 if (!IntExprEvaluator(Info, Result).Visit(E))
15623 LV.moveInto(Result);
15625 llvm::APFloat F(0.0);
15633 C.moveInto(Result);
15635 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
15640 P.moveInto(Result);
15645 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
15652 Info.CurrentCall->createTemporary(E,
T, ScopeKind::FullExpression, LV);
15657 if (!Info.getLangOpts().CPlusPlus11)
15658 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
15663 QualType Unqual =
T.getAtomicUnqualifiedType();
15667 E, Unqual, ScopeKind::FullExpression, LV);
15675 }
else if (Info.getLangOpts().CPlusPlus11) {
15676 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
15679 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15690 const Expr *E,
bool AllowNonLiteralTypes) {
15705 QualType Unqual =
T.getAtomicUnqualifiedType();
15726 if (Info.EnableNewConstInterp) {
15727 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
15730 ConstantExprKind::Normal);
15739 LV.setFrom(Info.Ctx, Result);
15746 ConstantExprKind::Normal) &&
15756 L->getType()->isUnsignedIntegerType()));
15761 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
15767 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
15768 if (CE->hasAPValueResult()) {
15769 Result.Val = CE->getAPValueResult();
15844 bool InConstantContext)
const {
15845 assert(!isValueDependent() &&
15846 "Expression evaluator can't be called on a dependent expression.");
15847 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
15848 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
15849 Info.InConstantContext = InConstantContext;
15850 return ::EvaluateAsRValue(
this, Result, Ctx, Info);
15854 bool InConstantContext)
const {
15855 assert(!isValueDependent() &&
15856 "Expression evaluator can't be called on a dependent expression.");
15857 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
15865 bool InConstantContext)
const {
15866 assert(!isValueDependent() &&
15867 "Expression evaluator can't be called on a dependent expression.");
15868 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
15869 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
15870 Info.InConstantContext = InConstantContext;
15871 return ::EvaluateAsInt(
this, Result, Ctx, AllowSideEffects, Info);
15876 bool InConstantContext)
const {
15877 assert(!isValueDependent() &&
15878 "Expression evaluator can't be called on a dependent expression.");
15879 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
15880 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
15881 Info.InConstantContext = InConstantContext;
15882 return ::EvaluateAsFixedPoint(
this, Result, Ctx, AllowSideEffects, Info);
15887 bool InConstantContext)
const {
15888 assert(!isValueDependent() &&
15889 "Expression evaluator can't be called on a dependent expression.");
15891 if (!getType()->isRealFloatingType())
15894 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
15906 bool InConstantContext)
const {
15907 assert(!isValueDependent() &&
15908 "Expression evaluator can't be called on a dependent expression.");
15910 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
15911 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
15912 Info.InConstantContext = InConstantContext;
15915 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
15916 Result.HasSideEffects ||
15919 ConstantExprKind::Normal, CheckedTemps))
15922 LV.moveInto(Result.Val);
15929 bool IsConstantDestruction) {
15930 EvalInfo Info(Ctx, EStatus,
15931 IsConstantDestruction ? EvalInfo::EM_ConstantExpression
15932 : EvalInfo::EM_ConstantFold);
15933 Info.setEvaluatingDecl(
Base, DestroyedValue,
15934 EvalInfo::EvaluatingDeclKind::Dtor);
15935 Info.InConstantContext = IsConstantDestruction;
15944 if (!Info.discardCleanups())
15945 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
15952 assert(!isValueDependent() &&
15953 "Expression evaluator can't be called on a dependent expression.");
15958 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
15959 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
15960 EvalInfo Info(Ctx, Result, EM);
15961 Info.InConstantContext =
true;
15963 if (Info.EnableNewConstInterp) {
15964 if (!Info.Ctx.getInterpContext().evaluate(Info,
this, Result.Val))
15967 getStorageType(Ctx,
this), Result.Val, Kind);
15972 if (Kind == ConstantExprKind::ClassTemplateArgument)
15980 Info.setEvaluatingDecl(
Base, Result.Val);
15982 if (Info.EnableNewConstInterp) {
15983 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info,
this, Result.Val))
15992 FullExpressionRAII
Scope(Info);
15994 Result.HasSideEffects || !
Scope.destroy())
15997 if (!Info.discardCleanups())
15998 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16009 if (Kind == ConstantExprKind::ClassTemplateArgument &&
16012 Result.HasSideEffects)) {
16024 bool IsConstantInitialization)
const {
16025 assert(!isValueDependent() &&
16026 "Expression evaluator can't be called on a dependent expression.");
16028 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
16030 llvm::raw_string_ostream OS(Name);
16036 EStatus.
Diag = &Notes;
16038 EvalInfo Info(Ctx, EStatus,
16039 (IsConstantInitialization &&
16041 ? EvalInfo::EM_ConstantExpression
16042 : EvalInfo::EM_ConstantFold);
16043 Info.setEvaluatingDecl(VD,
Value);
16044 Info.InConstantContext = IsConstantInitialization;
16049 if (Info.EnableNewConstInterp) {
16050 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
16051 if (!InterpCtx.evaluateAsInitializer(Info, VD,
Value))
16055 ConstantExprKind::Normal);
16070 FullExpressionRAII
Scope(Info);
16073 EStatus.HasSideEffects)
16079 Info.performLifetimeExtension();
16081 if (!Info.discardCleanups())
16082 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
16086 ConstantExprKind::Normal) &&
16093 EStatus.
Diag = &Notes;
16097 bool IsConstantDestruction = hasConstantInitialization();
16103 if (getEvaluatedValue() && !getEvaluatedValue()->isAbsent())
16104 DestroyedValue = *getEvaluatedValue();
16109 getType(), getLocation(), EStatus,
16110 IsConstantDestruction) ||
16114 ensureEvaluatedStmt()->HasConstantDestruction =
true;
16121 assert(!isValueDependent() &&
16122 "Expression evaluator can't be called on a dependent expression.");
16131 assert(!isValueDependent() &&
16132 "Expression evaluator can't be called on a dependent expression.");
16134 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
16137 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16138 Info.InConstantContext =
true;
16142 assert(Result &&
"Could not evaluate expression");
16143 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16145 return EVResult.Val.getInt();
16150 assert(!isValueDependent() &&
16151 "Expression evaluator can't be called on a dependent expression.");
16153 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
16156 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16157 Info.InConstantContext =
true;
16158 Info.CheckingForUndefinedBehavior =
true;
16162 assert(Result &&
"Could not evaluate expression");
16163 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
16165 return EVResult.Val.getInt();
16169 assert(!isValueDependent() &&
16170 "Expression evaluator can't be called on a dependent expression.");
16172 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
16176 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
16177 Info.CheckingForUndefinedBehavior =
true;
16210 IK_ICEIfUnevaluated,
16226static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
16231 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16233 Info.InConstantContext =
true;
16242 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
16247#define ABSTRACT_STMT(Node)
16248#define STMT(Node, Base) case Expr::Node##Class:
16249#define EXPR(Node, Base)
16250#include "clang/AST/StmtNodes.inc"
16251 case Expr::PredefinedExprClass:
16252 case Expr::FloatingLiteralClass:
16253 case Expr::ImaginaryLiteralClass:
16254 case Expr::StringLiteralClass:
16255 case Expr::ArraySubscriptExprClass:
16256 case Expr::MatrixSubscriptExprClass:
16257 case Expr::ArraySectionExprClass:
16258 case Expr::OMPArrayShapingExprClass:
16259 case Expr::OMPIteratorExprClass:
16260 case Expr::MemberExprClass:
16261 case Expr::CompoundAssignOperatorClass:
16262 case Expr::CompoundLiteralExprClass:
16263 case Expr::ExtVectorElementExprClass:
16264 case Expr::DesignatedInitExprClass:
16265 case Expr::ArrayInitLoopExprClass:
16266 case Expr::ArrayInitIndexExprClass:
16267 case Expr::NoInitExprClass:
16268 case Expr::DesignatedInitUpdateExprClass:
16269 case Expr::ImplicitValueInitExprClass:
16270 case Expr::ParenListExprClass:
16271 case Expr::VAArgExprClass:
16272 case Expr::AddrLabelExprClass:
16273 case Expr::StmtExprClass:
16274 case Expr::CXXMemberCallExprClass:
16275 case Expr::CUDAKernelCallExprClass:
16276 case Expr::CXXAddrspaceCastExprClass:
16277 case Expr::CXXDynamicCastExprClass:
16278 case Expr::CXXTypeidExprClass:
16279 case Expr::CXXUuidofExprClass:
16280 case Expr::MSPropertyRefExprClass:
16281 case Expr::MSPropertySubscriptExprClass:
16282 case Expr::CXXNullPtrLiteralExprClass:
16283 case Expr::UserDefinedLiteralClass:
16284 case Expr::CXXThisExprClass:
16285 case Expr::CXXThrowExprClass:
16286 case Expr::CXXNewExprClass:
16287 case Expr::CXXDeleteExprClass:
16288 case Expr::CXXPseudoDestructorExprClass:
16289 case Expr::UnresolvedLookupExprClass:
16290 case Expr::TypoExprClass:
16291 case Expr::RecoveryExprClass:
16292 case Expr::DependentScopeDeclRefExprClass:
16293 case Expr::CXXConstructExprClass:
16294 case Expr::CXXInheritedCtorInitExprClass:
16295 case Expr::CXXStdInitializerListExprClass:
16296 case Expr::CXXBindTemporaryExprClass:
16297 case Expr::ExprWithCleanupsClass:
16298 case Expr::CXXTemporaryObjectExprClass:
16299 case Expr::CXXUnresolvedConstructExprClass:
16300 case Expr::CXXDependentScopeMemberExprClass:
16301 case Expr::UnresolvedMemberExprClass:
16302 case Expr::ObjCStringLiteralClass:
16303 case Expr::ObjCBoxedExprClass:
16304 case Expr::ObjCArrayLiteralClass:
16305 case Expr::ObjCDictionaryLiteralClass:
16306 case Expr::ObjCEncodeExprClass:
16307 case Expr::ObjCMessageExprClass:
16308 case Expr::ObjCSelectorExprClass:
16309 case Expr::ObjCProtocolExprClass:
16310 case Expr::ObjCIvarRefExprClass:
16311 case Expr::ObjCPropertyRefExprClass:
16312 case Expr::ObjCSubscriptRefExprClass:
16313 case Expr::ObjCIsaExprClass:
16314 case Expr::ObjCAvailabilityCheckExprClass:
16315 case Expr::ShuffleVectorExprClass:
16316 case Expr::ConvertVectorExprClass:
16317 case Expr::BlockExprClass:
16318 case Expr::NoStmtClass:
16319 case Expr::OpaqueValueExprClass:
16320 case Expr::PackExpansionExprClass:
16321 case Expr::SubstNonTypeTemplateParmPackExprClass:
16322 case Expr::FunctionParmPackExprClass:
16323 case Expr::AsTypeExprClass:
16324 case Expr::ObjCIndirectCopyRestoreExprClass:
16325 case Expr::MaterializeTemporaryExprClass:
16326 case Expr::PseudoObjectExprClass:
16327 case Expr::AtomicExprClass:
16328 case Expr::LambdaExprClass:
16329 case Expr::CXXFoldExprClass:
16330 case Expr::CoawaitExprClass:
16331 case Expr::DependentCoawaitExprClass:
16332 case Expr::CoyieldExprClass:
16333 case Expr::SYCLUniqueStableNameExprClass:
16334 case Expr::CXXParenListInitExprClass:
16337 case Expr::InitListExprClass: {
16343 if (cast<InitListExpr>(E)->getNumInits() == 1)
16344 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
16348 case Expr::SizeOfPackExprClass:
16349 case Expr::GNUNullExprClass:
16350 case Expr::SourceLocExprClass:
16353 case Expr::PackIndexingExprClass:
16354 return CheckICE(cast<PackIndexingExpr>(E)->getSelectedExpr(), Ctx);
16356 case Expr::SubstNonTypeTemplateParmExprClass:
16358 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
16360 case Expr::ConstantExprClass:
16361 return CheckICE(cast<ConstantExpr>(E)->getSubExpr(), Ctx);
16363 case Expr::ParenExprClass:
16364 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
16365 case Expr::GenericSelectionExprClass:
16366 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
16367 case Expr::IntegerLiteralClass:
16368 case Expr::FixedPointLiteralClass:
16369 case Expr::CharacterLiteralClass:
16370 case Expr::ObjCBoolLiteralExprClass:
16371 case Expr::CXXBoolLiteralExprClass:
16372 case Expr::CXXScalarValueInitExprClass:
16373 case Expr::TypeTraitExprClass:
16374 case Expr::ConceptSpecializationExprClass:
16375 case Expr::RequiresExprClass:
16376 case Expr::ArrayTypeTraitExprClass:
16377 case Expr::ExpressionTraitExprClass:
16378 case Expr::CXXNoexceptExprClass:
16380 case Expr::CallExprClass:
16381 case Expr::CXXOperatorCallExprClass: {
16385 const CallExpr *CE = cast<CallExpr>(E);
16390 case Expr::CXXRewrittenBinaryOperatorClass:
16391 return CheckICE(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm(),
16393 case Expr::DeclRefExprClass: {
16394 const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
16395 if (isa<EnumConstantDecl>(D))
16407 const VarDecl *VD = dyn_cast<VarDecl>(D);
16414 case Expr::UnaryOperatorClass: {
16437 llvm_unreachable(
"invalid unary operator class");
16439 case Expr::OffsetOfExprClass: {
16448 case Expr::UnaryExprOrTypeTraitExprClass: {
16450 if ((Exp->
getKind() == UETT_SizeOf) &&
16455 case Expr::BinaryOperatorClass: {
16500 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
16503 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
16504 if (REval.isSigned() && REval.isAllOnes()) {
16506 if (LEval.isMinSignedValue())
16507 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
16515 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
16516 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
16522 return Worst(LHSResult, RHSResult);
16528 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
16538 return Worst(LHSResult, RHSResult);
16541 llvm_unreachable(
"invalid binary operator kind");
16543 case Expr::ImplicitCastExprClass:
16544 case Expr::CStyleCastExprClass:
16545 case Expr::CXXFunctionalCastExprClass:
16546 case Expr::CXXStaticCastExprClass:
16547 case Expr::CXXReinterpretCastExprClass:
16548 case Expr::CXXConstCastExprClass:
16549 case Expr::ObjCBridgedCastExprClass: {
16550 const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
16551 if (isa<ExplicitCastExpr>(E)) {
16556 APSInt IgnoredVal(DestWidth, !DestSigned);
16561 if (FL->getValue().convertToInteger(IgnoredVal,
16562 llvm::APFloat::rmTowardZero,
16563 &Ignored) & APFloat::opInvalidOp)
16568 switch (cast<CastExpr>(E)->getCastKind()) {
16569 case CK_LValueToRValue:
16570 case CK_AtomicToNonAtomic:
16571 case CK_NonAtomicToAtomic:
16573 case CK_IntegralToBoolean:
16574 case CK_IntegralCast:
16580 case Expr::BinaryConditionalOperatorClass: {
16583 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
16585 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
16586 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
16587 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
16589 return FalseResult;
16591 case Expr::ConditionalOperatorClass: {
16599 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
16602 if (CondResult.Kind == IK_NotICE)
16608 if (TrueResult.Kind == IK_NotICE)
16610 if (FalseResult.Kind == IK_NotICE)
16611 return FalseResult;
16612 if (CondResult.Kind == IK_ICEIfUnevaluated)
16614 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
16620 return FalseResult;
16623 case Expr::CXXDefaultArgExprClass:
16624 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
16625 case Expr::CXXDefaultInitExprClass:
16626 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
16627 case Expr::ChooseExprClass: {
16628 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
16630 case Expr::BuiltinBitCastExprClass: {
16631 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(E)))
16633 return CheckICE(cast<CastExpr>(E)->getSubExpr(), Ctx);
16637 llvm_unreachable(
"Invalid StmtClass!");
16643 llvm::APSInt *
Value,
16654 if (!Result.isInt()) {
16665 assert(!isValueDependent() &&
16666 "Expression evaluator can't be called on a dependent expression.");
16668 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
16674 if (D.Kind != IK_ICE) {
16681std::optional<llvm::APSInt>
16683 if (isValueDependent()) {
16685 return std::nullopt;
16693 return std::nullopt;
16696 if (!isIntegerConstantExpr(Ctx,
Loc))
16697 return std::nullopt;
16705 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
16706 Info.InConstantContext =
true;
16709 llvm_unreachable(
"ICE cannot be evaluated!");
16715 assert(!isValueDependent() &&
16716 "Expression evaluator can't be called on a dependent expression.");
16718 return CheckICE(
this, Ctx).Kind == IK_ICE;
16723 assert(!isValueDependent() &&
16724 "Expression evaluator can't be called on a dependent expression.");
16733 Status.Diag = &Diags;
16734 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16741 Info.discardCleanups() && !Status.HasSideEffects;
16743 if (!Diags.empty()) {
16744 IsConstExpr =
false;
16745 if (
Loc) *
Loc = Diags[0].first;
16746 }
else if (!IsConstExpr) {
16748 if (
Loc) *
Loc = getExprLoc();
16751 return IsConstExpr;
16757 const Expr *This)
const {
16758 assert(!isValueDependent() &&
16759 "Expression evaluator can't be called on a dependent expression.");
16761 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
16763 llvm::raw_string_ostream OS(Name);
16770 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
16771 Info.InConstantContext =
true;
16774 const LValue *ThisPtr =
nullptr;
16777 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
16778 assert(MD &&
"Don't provide `this` for non-methods.");
16779 assert(MD->isImplicitObjectMemberFunction() &&
16780 "Don't provide `this` for methods without an implicit object.");
16782 if (!This->isValueDependent() &&
16784 !Info.EvalStatus.HasSideEffects)
16785 ThisPtr = &ThisVal;
16789 Info.EvalStatus.HasSideEffects =
false;
16792 CallRef
Call = Info.CurrentCall->createCall(Callee);
16795 unsigned Idx = I - Args.begin();
16796 if (Idx >= Callee->getNumParams())
16798 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
16799 if ((*I)->isValueDependent() ||
16801 Info.EvalStatus.HasSideEffects) {
16803 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
16809 Info.EvalStatus.HasSideEffects =
false;
16814 Info.discardCleanups();
16815 Info.EvalStatus.HasSideEffects =
false;
16818 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr, This,
16821 FullExpressionRAII
Scope(Info);
16823 !Info.EvalStatus.HasSideEffects;
16835 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
16837 llvm::raw_string_ostream OS(Name);
16844 Status.Diag = &Diags;
16846 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
16847 Info.InConstantContext =
true;
16848 Info.CheckingPotentialConstantExpression =
true;
16851 if (Info.EnableNewConstInterp) {
16852 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
16853 return Diags.empty();
16863 This.set({&VIE, Info.CurrentCall->Index});
16871 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
16877 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
16881 return Diags.empty();
16889 "Expression evaluator can't be called on a dependent expression.");
16892 Status.Diag = &Diags;
16895 EvalInfo::EM_ConstantExpressionUnevaluated);
16896 Info.InConstantContext =
true;
16897 Info.CheckingPotentialConstantExpression =
true;
16901 nullptr, CallRef());
16905 return Diags.empty();
16909 unsigned Type)
const {
16910 if (!getType()->isPointerType())
16914 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
16931 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
16932 String.getLValueBase().dyn_cast<
const Expr *>())) {
16933 StringRef Str = S->getBytes();
16934 int64_t Off = String.Offset.getQuantity();
16935 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
16936 S->getCharByteWidth() == 1 &&
16938 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
16939 Str = Str.substr(Off);
16941 StringRef::size_type Pos = Str.find(0);
16942 if (Pos != StringRef::npos)
16943 Str = Str.substr(0, Pos);
16945 Result = Str.size();
16953 for (uint64_t Strlen = 0; ; ++Strlen) {
16968 const Expr *SizeExpression,
16972 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
16973 Info.InConstantContext =
true;
16975 FullExpressionRAII
Scope(Info);
16980 uint64_t Size = SizeValue.getZExtValue();
16986 for (uint64_t I = 0; I < Size; ++I) {
16993 Result.push_back(
static_cast<char>(
C.getExtValue()));
16997 if (!
Scope.destroy())
17008 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 bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool 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
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
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.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
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)