55 #include "llvm/ADT/Optional.h" 56 #include "llvm/ADT/SmallBitVector.h" 57 #include "llvm/Support/SaveAndRestore.h" 58 #include "llvm/Support/raw_ostream.h" 62 #define DEBUG_TYPE "exprconstant" 64 using namespace clang;
75 using SourceLocExprScopeGuard =
88 for (
auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
89 Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
108 dyn_cast<MaterializeTemporaryExpr>(Base)) {
111 const Expr *Temp = MTE->getSubExpr();
116 if (!Adjustments.empty())
148 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
150 return Callee ? Callee->
getAttr<AllocSizeAttr>() :
nullptr;
157 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
165 if (
const auto *FE = dyn_cast<FullExpr>(E))
168 if (
const auto *
Cast = dyn_cast<CastExpr>(E))
169 E =
Cast->getSubExpr()->IgnoreParens();
171 if (
const auto *CE = dyn_cast<CallExpr>(E))
172 return getAllocSizeAttr(CE) ? CE :
nullptr;
186 static const uint64_t AssumedSizeForUnsizedArray =
197 bool &FirstEntryIsUnsizedArray) {
200 assert(!isBaseAnAllocSizeCall(Base) &&
201 "Unsized arrays shouldn't appear here");
202 unsigned MostDerivedLength = 0;
203 Type = getType(Base);
205 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
209 MostDerivedLength = I + 1;
212 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
213 ArraySize = CAT->getSize().getZExtValue();
215 assert(I == 0 &&
"unexpected unsized array designator");
216 FirstEntryIsUnsizedArray =
true;
217 ArraySize = AssumedSizeForUnsizedArray;
223 MostDerivedLength = I + 1;
225 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
226 Type = FD->getType();
228 MostDerivedLength = I + 1;
236 return MostDerivedLength;
240 struct SubobjectDesignator {
244 unsigned Invalid : 1;
247 unsigned IsOnePastTheEnd : 1;
250 unsigned FirstEntryIsAnUnsizedArray : 1;
253 unsigned MostDerivedIsArrayElement : 1;
257 unsigned MostDerivedPathLength : 28;
266 uint64_t MostDerivedArraySize;
276 SubobjectDesignator() : Invalid(
true) {}
278 explicit SubobjectDesignator(
QualType T)
279 : Invalid(
false), IsOnePastTheEnd(
false),
280 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
281 MostDerivedPathLength(0), MostDerivedArraySize(0),
282 MostDerivedType(T) {}
286 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
287 MostDerivedPathLength(0), MostDerivedArraySize(0) {
288 assert(V.
isLValue() &&
"Non-LValue used to make an LValue designator?");
292 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
294 bool IsArray =
false;
295 bool FirstIsUnsizedArray =
false;
296 MostDerivedPathLength = findMostDerivedSubobject(
298 MostDerivedType, IsArray, FirstIsUnsizedArray);
299 MostDerivedIsArrayElement = IsArray;
300 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
306 unsigned NewLength) {
310 assert(Base &&
"cannot truncate path for null pointer");
311 assert(NewLength <= Entries.size() &&
"not a truncation");
313 if (NewLength == Entries.size())
315 Entries.resize(NewLength);
317 bool IsArray =
false;
318 bool FirstIsUnsizedArray =
false;
319 MostDerivedPathLength = findMostDerivedSubobject(
320 Ctx, Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
321 FirstIsUnsizedArray);
322 MostDerivedIsArrayElement = IsArray;
323 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
333 bool isMostDerivedAnUnsizedArray()
const {
334 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
335 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
340 uint64_t getMostDerivedArraySize()
const {
341 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
342 return MostDerivedArraySize;
346 bool isOnePastTheEnd()
const {
350 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
351 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
352 MostDerivedArraySize)
360 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
361 if (Invalid || isMostDerivedAnUnsizedArray())
367 bool IsArray = MostDerivedPathLength == Entries.size() &&
368 MostDerivedIsArrayElement;
369 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
370 : (uint64_t)IsOnePastTheEnd;
372 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
373 return {ArrayIndex, ArraySize - ArrayIndex};
377 bool isValidSubobject()
const {
380 return !isOnePastTheEnd();
388 assert(!Invalid &&
"invalid designator has no subobject type");
389 return MostDerivedPathLength == Entries.size()
396 Entries.push_back(PathEntry::ArrayIndex(0));
400 MostDerivedIsArrayElement =
true;
401 MostDerivedArraySize = CAT->
getSize().getZExtValue();
402 MostDerivedPathLength = Entries.size();
406 void addUnsizedArrayUnchecked(
QualType ElemTy) {
407 Entries.push_back(PathEntry::ArrayIndex(0));
409 MostDerivedType = ElemTy;
410 MostDerivedIsArrayElement =
true;
414 MostDerivedArraySize = AssumedSizeForUnsizedArray;
415 MostDerivedPathLength = Entries.size();
419 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
423 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
424 MostDerivedType = FD->getType();
425 MostDerivedIsArrayElement =
false;
426 MostDerivedArraySize = 0;
427 MostDerivedPathLength = Entries.size();
431 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
432 Entries.push_back(PathEntry::ArrayIndex(Imag));
436 MostDerivedType = EltTy;
437 MostDerivedIsArrayElement =
true;
438 MostDerivedArraySize = 2;
439 MostDerivedPathLength = Entries.size();
441 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
442 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
445 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N) {
446 if (Invalid || !N)
return;
447 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
448 if (isMostDerivedAnUnsizedArray()) {
449 diagnoseUnsizedArrayPointerArithmetic(Info, E);
453 Entries.back() = PathEntry::ArrayIndex(
454 Entries.back().getAsArrayIndex() + TruncatedN);
461 bool IsArray = MostDerivedPathLength == Entries.size() &&
462 MostDerivedIsArrayElement;
463 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
464 : (uint64_t)IsOnePastTheEnd;
466 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
468 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
471 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
473 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
474 diagnosePointerArithmetic(Info, E, N);
479 ArrayIndex += TruncatedN;
480 assert(ArrayIndex <= ArraySize &&
481 "bounds check succeeded for out-of-bounds index");
484 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
486 IsOnePastTheEnd = (ArrayIndex != 0);
496 CallStackFrame *Caller;
514 typedef std::pair<const void *, unsigned> MapKeyTy;
515 typedef std::map<MapKeyTy, APValue>
MapTy;
527 unsigned CurTempVersion = TempVersionStack.back();
529 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
531 void pushTempVersion() {
532 TempVersionStack.push_back(++CurTempVersion);
535 void popTempVersion() {
536 TempVersionStack.pop_back();
547 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
556 APValue *getTemporary(
const void *Key,
unsigned Version) {
557 MapKeyTy KV(Key, Version);
558 auto LB = Temporaries.lower_bound(KV);
559 if (LB != Temporaries.end() && LB->first == KV)
563 assert((LB == Temporaries.end() || LB->first.first != Key) &&
564 (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) &&
565 "Element with key 'Key' found in map");
570 APValue *getCurrentTemporary(
const void *Key) {
571 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
572 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
573 return &std::prev(UB)->second;
578 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
579 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
580 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
581 return std::prev(UB)->first.second;
589 template<
typename KeyT>
591 bool IsLifetimeExtended, LValue &LV);
593 void describe(llvm::raw_ostream &OS)
override;
595 Frame *getCaller()
const override {
return Caller; }
596 SourceLocation getCallLocation()
const override {
return CallLoc; }
597 const FunctionDecl *getCallee()
const override {
return Callee; }
599 bool isStdFunction()
const {
601 if (DC->isStdNamespace())
608 class ThisOverrideRAII {
610 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
611 : Frame(Frame), OldThis(Frame.This) {
613 Frame.This = NewThis;
615 ~ThisOverrideRAII() {
616 Frame.This = OldThis;
619 CallStackFrame &Frame;
620 const LValue *OldThis;
633 llvm::PointerIntPair<APValue*, 1, bool>
Value;
639 bool IsLifetimeExtended)
640 :
Value(Val, IsLifetimeExtended), Base(Base), T(T) {}
642 bool isLifetimeExtended()
const {
return Value.getInt(); }
643 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
644 if (RunDestructors) {
647 Loc = VD->getLocation();
652 *Value.getPointer() =
APValue();
656 bool hasSideEffect() {
662 struct ObjectUnderConstruction {
665 friend bool operator==(
const ObjectUnderConstruction &LHS,
666 const ObjectUnderConstruction &RHS) {
667 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
669 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
686 return {Base::getEmptyKey(), {}}; }
688 return {Base::getTombstoneKey(), {}};
693 static bool isEqual(
const ObjectUnderConstruction &LHS,
694 const ObjectUnderConstruction &RHS) {
708 const Expr *AllocExpr =
nullptr;
719 if (
auto *
NE = dyn_cast<CXXNewExpr>(AllocExpr))
720 return NE->isArray() ? ArrayNew : New;
721 assert(isa<CallExpr>(AllocExpr));
726 struct DynAllocOrder {
754 CallStackFrame *CurrentCall;
757 unsigned CallStackDepth;
760 unsigned NextCallIndex;
769 bool EnableNewConstInterp;
773 CallStackFrame BottomFrame;
783 enum class EvaluatingDeclKind {
797 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
798 ObjectsUnderConstruction;
803 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
806 unsigned NumHeapAllocs = 0;
808 struct EvaluatingConstructorRAII {
810 ObjectUnderConstruction Object;
812 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
814 : EI(EI), Object(Object) {
816 EI.ObjectsUnderConstruction
817 .insert({Object, HasBases ? ConstructionPhase::Bases
818 : ConstructionPhase::AfterBases})
821 void finishedConstructingBases() {
822 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
824 ~EvaluatingConstructorRAII() {
825 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
829 struct EvaluatingDestructorRAII {
831 ObjectUnderConstruction Object;
833 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
834 : EI(EI), Object(Object) {
835 DidInsert = EI.ObjectsUnderConstruction
836 .insert({Object, ConstructionPhase::Destroying})
839 void startedDestroyingBases() {
840 EI.ObjectsUnderConstruction[Object] =
841 ConstructionPhase::DestroyingBases;
843 ~EvaluatingDestructorRAII() {
845 EI.ObjectsUnderConstruction.erase(Object);
852 return ObjectsUnderConstruction.lookup({Base, Path});
857 unsigned SpeculativeEvaluationDepth = 0;
861 uint64_t ArrayInitIndex = -1;
865 bool HasActiveDiagnostic;
869 bool HasFoldFailureDiagnostic;
873 bool InConstantContext;
878 bool CheckingPotentialConstantExpression =
false;
883 bool CheckingForUndefinedBehavior =
false;
885 enum EvaluationMode {
888 EM_ConstantExpression,
895 EM_ConstantExpressionUnevaluated,
903 EM_IgnoreSideEffects,
908 bool checkingPotentialConstantExpression()
const override {
909 return CheckingPotentialConstantExpression;
915 bool checkingForUndefinedBehavior()
const override {
916 return CheckingForUndefinedBehavior;
920 : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(
nullptr),
921 CallStackDepth(0), NextCallIndex(1),
923 EnableNewConstInterp(C.
getLangOpts().EnableNewConstInterp),
925 EvaluatingDecl((
const ValueDecl *)
nullptr),
926 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
927 HasFoldFailureDiagnostic(
false), InConstantContext(
false),
935 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
936 EvaluatingDecl = Base;
937 IsEvaluatingDecl = EDK;
938 EvaluatingDeclValue = &
Value;
944 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
946 if (NextCallIndex == 0) {
948 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
951 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
953 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
954 << getLangOpts().ConstexprCallDepth;
958 std::pair<CallStackFrame *, unsigned>
959 getCallFrameAndDepth(
unsigned CallIndex) {
960 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
963 unsigned Depth = CallStackDepth;
964 CallStackFrame *Frame = CurrentCall;
965 while (Frame->Index > CallIndex) {
966 Frame = Frame->Caller;
969 if (Frame->Index == CallIndex)
970 return {Frame, Depth};
974 bool nextStep(
const Stmt *S) {
976 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
987 auto It = HeapAllocs.find(DA);
988 if (It != HeapAllocs.end())
989 Result = &It->second;
994 struct StdAllocatorCaller {
997 explicit operator bool()
const {
return FrameIndex != 0; };
1000 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1001 for (
const CallStackFrame *Call = CurrentCall; Call != &BottomFrame;
1002 Call = Call->Caller) {
1003 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Call->Callee);
1007 if (!FnII || !FnII->
isStr(FnName))
1017 if (CTSD->isInStdNamespace() && ClassII &&
1018 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1020 return {Call->Index, TAL[0].getAsType()};
1026 void performLifetimeExtension() {
1029 std::remove_if(CleanupStack.begin(), CleanupStack.end(),
1030 [](Cleanup &
C) {
return C.isLifetimeExtended(); }),
1031 CleanupStack.end());
1037 bool discardCleanups() {
1038 for (Cleanup &C : CleanupStack) {
1039 if (C.hasSideEffect() && !noteSideEffect()) {
1040 CleanupStack.clear();
1044 CleanupStack.clear();
1049 interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1050 const interp::Frame *getBottomFrame()
const override {
return &BottomFrame; }
1052 bool hasActiveDiagnostic()
override {
return HasActiveDiagnostic; }
1053 void setActiveDiagnostic(
bool Flag)
override { HasActiveDiagnostic = Flag; }
1055 void setFoldFailureDiagnostic(
bool Flag)
override {
1056 HasFoldFailureDiagnostic = Flag;
1061 ASTContext &getCtx()
const override {
return Ctx; }
1069 bool hasPriorDiagnostic()
override {
1070 if (!EvalStatus.
Diag->empty()) {
1072 case EM_ConstantFold:
1073 case EM_IgnoreSideEffects:
1074 if (!HasFoldFailureDiagnostic)
1078 case EM_ConstantExpression:
1079 case EM_ConstantExpressionUnevaluated:
1080 setActiveDiagnostic(
false);
1087 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1092 bool keepEvaluatingAfterSideEffect() {
1094 case EM_IgnoreSideEffects:
1097 case EM_ConstantExpression:
1098 case EM_ConstantExpressionUnevaluated:
1099 case EM_ConstantFold:
1102 return checkingPotentialConstantExpression() ||
1103 checkingForUndefinedBehavior();
1105 llvm_unreachable(
"Missed EvalMode case");
1110 bool noteSideEffect() {
1112 return keepEvaluatingAfterSideEffect();
1116 bool keepEvaluatingAfterUndefinedBehavior() {
1118 case EM_IgnoreSideEffects:
1119 case EM_ConstantFold:
1122 case EM_ConstantExpression:
1123 case EM_ConstantExpressionUnevaluated:
1124 return checkingForUndefinedBehavior();
1126 llvm_unreachable(
"Missed EvalMode case");
1132 bool noteUndefinedBehavior()
override {
1134 return keepEvaluatingAfterUndefinedBehavior();
1139 bool keepEvaluatingAfterFailure()
const override {
1144 case EM_ConstantExpression:
1145 case EM_ConstantExpressionUnevaluated:
1146 case EM_ConstantFold:
1147 case EM_IgnoreSideEffects:
1148 return checkingPotentialConstantExpression() ||
1149 checkingForUndefinedBehavior();
1151 llvm_unreachable(
"Missed EvalMode case");
1164 LLVM_NODISCARD
bool noteFailure() {
1172 bool KeepGoing = keepEvaluatingAfterFailure();
1177 class ArrayInitLoopIndex {
1179 uint64_t OuterIndex;
1182 ArrayInitLoopIndex(EvalInfo &Info)
1183 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1184 Info.ArrayInitIndex = 0;
1186 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1188 operator uint64_t&() {
return Info.ArrayInitIndex; }
1193 struct FoldConstant {
1196 bool HadNoPriorDiags;
1197 EvalInfo::EvaluationMode OldMode;
1199 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1202 HadNoPriorDiags(Info.EvalStatus.Diag &&
1203 Info.EvalStatus.Diag->empty() &&
1204 !Info.EvalStatus.HasSideEffects),
1205 OldMode(Info.EvalMode) {
1207 Info.EvalMode = EvalInfo::EM_ConstantFold;
1209 void keepDiagnostics() { Enabled =
false; }
1211 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1212 !Info.EvalStatus.HasSideEffects)
1213 Info.EvalStatus.Diag->clear();
1214 Info.EvalMode = OldMode;
1220 struct IgnoreSideEffectsRAII {
1222 EvalInfo::EvaluationMode OldMode;
1223 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1224 : Info(Info), OldMode(Info.EvalMode) {
1225 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1228 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1233 class SpeculativeEvaluationRAII {
1234 EvalInfo *Info =
nullptr;
1236 unsigned OldSpeculativeEvaluationDepth;
1238 void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
1240 OldStatus = Other.OldStatus;
1241 OldSpeculativeEvaluationDepth = Other.OldSpeculativeEvaluationDepth;
1242 Other.Info =
nullptr;
1245 void maybeRestoreState() {
1249 Info->EvalStatus = OldStatus;
1250 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1254 SpeculativeEvaluationRAII() =
default;
1256 SpeculativeEvaluationRAII(
1258 : Info(&Info), OldStatus(Info.EvalStatus),
1259 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1260 Info.EvalStatus.Diag = NewDiag;
1261 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1264 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &Other) =
delete;
1265 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&Other) {
1266 moveFromAndCancel(std::move(Other));
1269 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&Other) {
1270 maybeRestoreState();
1271 moveFromAndCancel(std::move(Other));
1275 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1280 template<
bool IsFullExpression>
1283 unsigned OldStackSize;
1285 ScopeRAII(EvalInfo &Info)
1286 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1289 Info.CurrentCall->pushTempVersion();
1291 bool destroy(
bool RunDestructors =
true) {
1292 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1297 if (OldStackSize != -1U)
1301 Info.CurrentCall->popTempVersion();
1304 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1305 unsigned OldStackSize) {
1306 assert(OldStackSize <= Info.CleanupStack.size() &&
1307 "running cleanups out of order?");
1311 bool Success =
true;
1312 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1313 if (!(IsFullExpression &&
1314 Info.CleanupStack[I - 1].isLifetimeExtended())) {
1315 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1323 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1324 if (IsFullExpression)
1326 std::remove_if(NewEnd, Info.CleanupStack.end(),
1327 [](Cleanup &
C) {
return !
C.isLifetimeExtended(); });
1328 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1332 typedef ScopeRAII<false> BlockScopeRAII;
1333 typedef ScopeRAII<true> FullExpressionRAII;
1336 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1340 if (isOnePastTheEnd()) {
1341 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1352 void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1354 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1359 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1364 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1365 Info.CCEDiag(E, diag::note_constexpr_array_index)
1367 <<
static_cast<unsigned>(getMostDerivedArraySize());
1369 Info.CCEDiag(E, diag::note_constexpr_array_index)
1374 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
1377 : Info(Info), Caller(Info.CurrentCall), Callee(Callee),
This(
This),
1378 Arguments(Arguments), CallLoc(CallLoc), Index(Info.NextCallIndex++) {
1379 Info.CurrentCall =
this;
1380 ++Info.CallStackDepth;
1383 CallStackFrame::~CallStackFrame() {
1384 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1385 --Info.CallStackDepth;
1386 Info.CurrentCall = Caller;
1408 llvm_unreachable(
"unknown access kind");
1421 struct ComplexValue {
1427 APFloat FloatReal, FloatImag;
1429 ComplexValue() : FloatReal(APFloat::Bogus()), FloatImag(APFloat::Bogus()) {}
1431 void makeComplexFloat() { IsInt =
false; }
1432 bool isComplexFloat()
const {
return !IsInt; }
1433 APFloat &getComplexFloatReal() {
return FloatReal; }
1434 APFloat &getComplexFloatImag() {
return FloatImag; }
1436 void makeComplexInt() { IsInt =
true; }
1437 bool isComplexInt()
const {
return IsInt; }
1438 APSInt &getComplexIntReal() {
return IntReal; }
1439 APSInt &getComplexIntImag() {
return IntImag; }
1442 if (isComplexFloat())
1443 v =
APValue(FloatReal, FloatImag);
1445 v =
APValue(IntReal, IntImag);
1447 void setFrom(
const APValue &v) {
1466 bool InvalidBase : 1;
1471 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1472 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1473 bool isNullPointer()
const {
return IsNullPtr;}
1475 unsigned getLValueCallIndex()
const {
return Base.
getCallIndex(); }
1476 unsigned getLValueVersion()
const {
return Base.
getVersion(); }
1479 if (Designator.Invalid)
1482 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1483 V =
APValue(Base, Offset, Designator.Entries,
1484 Designator.IsOnePastTheEnd, IsNullPtr);
1488 assert(V.
isLValue() &&
"Setting LValue from a non-LValue?");
1491 InvalidBase =
false;
1492 Designator = SubobjectDesignator(Ctx, V);
1500 const auto *E = B.get<
const Expr *>();
1501 assert((isa<MemberExpr>(E) || tryUnwrapAllocSizeCall(E)) &&
1502 "Unexpected type of invalid base");
1508 InvalidBase = BInvalid;
1509 Designator = SubobjectDesignator(getType(B));
1514 Base = (
Expr *)
nullptr;
1517 InvalidBase =
false;
1528 moveInto(Printable);
1535 template <
typename GenDiagType>
1536 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1537 if (Designator.Invalid)
1541 Designator.setInvalid();
1548 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1550 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1551 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1555 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1557 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1558 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1566 Designator.checkSubobject(Info, E, CSK);
1569 void addDecl(EvalInfo &Info,
const Expr *E,
1572 Designator.addDeclUnchecked(D,
Virtual);
1574 void addUnsizedArray(EvalInfo &Info,
const Expr *E,
QualType ElemTy) {
1575 if (!Designator.Entries.empty()) {
1576 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1577 Designator.setInvalid();
1581 assert(getType(Base)->isPointerType() || getType(Base)->isArrayType());
1582 Designator.FirstEntryIsAnUnsizedArray =
true;
1583 Designator.addUnsizedArrayUnchecked(ElemTy);
1588 Designator.addArrayUnchecked(CAT);
1590 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1592 Designator.addComplexUnchecked(EltTy, Imag);
1594 void clearIsNullPointer() {
1597 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1609 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1613 Designator.adjustIndex(Info, E, Index);
1614 clearIsNullPointer();
1619 clearIsNullPointer();
1626 DeclAndIsDerivedMember(Decl,
false), Path() {}
1631 return DeclAndIsDerivedMember.getPointer();
1634 bool isDerivedMember()
const {
1635 return DeclAndIsDerivedMember.getInt();
1639 return cast<CXXRecordDecl>(
1640 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1644 V =
APValue(getDecl(), isDerivedMember(), Path);
1646 void setFrom(
const APValue &V) {
1652 Path.insert(Path.end(), P.begin(), P.end());
1658 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1666 assert(!Path.empty());
1668 if (Path.size() >= 2)
1669 Expected = Path[Path.size() - 2];
1671 Expected = getContainingRecord();
1688 if (!isDerivedMember()) {
1689 Path.push_back(Derived);
1692 if (!castBack(Derived))
1695 DeclAndIsDerivedMember.setInt(
false);
1703 DeclAndIsDerivedMember.setInt(
true);
1704 if (isDerivedMember()) {
1705 Path.push_back(Base);
1708 return castBack(Base);
1713 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1714 if (!LHS.getDecl() || !RHS.getDecl())
1715 return !LHS.getDecl() && !RHS.getDecl();
1716 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1718 return LHS.Path == RHS.Path;
1725 bool AllowNonLiteralTypes =
false);
1727 bool InvalidBaseOK =
false);
1729 bool InvalidBaseOK =
false);
1757 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1758 Int = Int.extend(Int.getBitWidth() + 1);
1759 Int.setIsSigned(
true);
1764 template<
typename KeyT>
1766 bool IsLifetimeExtended, LValue &LV) {
1767 unsigned Version = getTempVersion();
1770 APValue &Result = Temporaries[MapKeyTy(Key, Version)];
1771 assert(Result.
isAbsent() &&
"temporary created multiple times");
1777 if (Index <= Info.SpeculativeEvaluationDepth) {
1779 Info.noteSideEffect();
1781 Info.CleanupStack.push_back(Cleanup(&Result, Base, T, IsLifetimeExtended));
1788 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1794 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1795 std::forward_as_tuple(DA), std::tuple<>());
1796 assert(Result.second &&
"reused a heap alloc index?");
1797 Result.first->second.AllocExpr = E;
1798 return &Result.first->second.Value;
1802 void CallStackFrame::describe(raw_ostream &Out) {
1803 unsigned ArgIndex = 0;
1804 bool IsMemberCall = isa<CXXMethodDecl>(Callee) &&
1805 !isa<CXXConstructorDecl>(Callee) &&
1806 cast<CXXMethodDecl>(Callee)->isInstance();
1809 Out << *Callee <<
'(';
1811 if (This && IsMemberCall) {
1813 This->moveInto(Val);
1815 This->Designator.MostDerivedType);
1817 Out <<
"->" << *Callee <<
'(';
1818 IsMemberCall =
false;
1822 E = Callee->param_end(); I != E; ++I, ++ArgIndex) {
1823 if (ArgIndex > (
unsigned)IsMemberCall)
1827 const APValue &Arg = Arguments[ArgIndex];
1830 if (ArgIndex == 0 && IsMemberCall)
1831 Out <<
"->" << *Callee <<
'(';
1844 return Info.noteSideEffect();
1851 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1852 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1861 if (!B)
return true;
1865 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1866 return VD->hasGlobalStorage();
1868 return isa<FunctionDecl>(D);
1878 case Expr::CompoundLiteralExprClass: {
1882 case Expr::MaterializeTemporaryExprClass:
1885 return cast<MaterializeTemporaryExpr>(E)->getStorageDuration() ==
SD_Static;
1887 case Expr::StringLiteralClass:
1888 case Expr::PredefinedExprClass:
1889 case Expr::ObjCStringLiteralClass:
1890 case Expr::ObjCEncodeExprClass:
1891 case Expr::CXXUuidofExprClass:
1893 case Expr::ObjCBoxedExprClass:
1894 return cast<ObjCBoxedExpr>(E)->isExpressibleAsConstantInitializer();
1895 case Expr::CallExprClass:
1898 case Expr::AddrLabelExprClass:
1902 case Expr::BlockExprClass:
1903 return !cast<BlockExpr>(E)->getBlockDecl()->hasCaptures();
1904 case Expr::ImplicitValueInitExprClass:
1916 return LVal.Base.dyn_cast<
const ValueDecl*>();
1920 if (Value.getLValueCallIndex())
1922 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1923 return E && !isa<MaterializeTemporaryExpr>(E);
1928 return Decl && Decl->
isWeak();
1933 if (Decl && isa<VarDecl>(Decl)) {
1943 if (!A.getLValueBase())
1944 return !B.getLValueBase();
1945 if (!B.getLValueBase())
1948 if (A.getLValueBase().getOpaqueValue() !=
1949 B.getLValueBase().getOpaqueValue()) {
1959 (A.getLValueCallIndex() == B.getLValueCallIndex() &&
1960 A.getLValueVersion() == B.getLValueVersion());
1964 assert(Base &&
"no location for a null lvalue");
1967 Info.Note(VD->
getLocation(), diag::note_declared_at);
1969 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
1973 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
1974 diag::note_constexpr_dynamic_alloc_here);
1987 llvm::SmallPtrSet<const MaterializeTemporaryExpr *, 8>;
2006 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2012 if (Info.getLangOpts().CPlusPlus11) {
2014 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2015 << IsReferenceType << !Designator.Entries.empty()
2024 assert((Info.checkingPotentialConstantExpression() ||
2025 LVal.getLValueCallIndex() == 0) &&
2026 "have call index for global lvalue");
2029 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2030 << IsReferenceType << !Designator.Entries.empty();
2036 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
2038 if (Var->getTLSKind())
2047 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
2059 FD->hasAttr<DLLImportAttr>())
2063 }
else if (
const auto *MTE = dyn_cast_or_null<MaterializeTemporaryExpr>(
2065 if (CheckedTemps.insert(MTE).second) {
2068 Info.FFDiag(MTE->getExprLoc(),
2069 diag::note_constexpr_unsupported_tempoarary_nontrivial_dtor)
2074 APValue *
V = MTE->getOrCreateValue(
false);
2075 assert(V &&
"evasluation result refers to uninitialised temporary");
2077 Info, MTE->getExprLoc(), TempType, *
V,
2085 if (!IsReferenceType)
2096 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
2098 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2099 << !Designator.Entries.empty() << !!VD << VD;
2114 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
2118 !FD->hasAttr<DLLImportAttr>();
2124 const LValue *This =
nullptr) {
2141 if (This && Info.EvaluatingDecl == This->getLValueBase())
2145 if (Info.getLangOpts().CPlusPlus11)
2146 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2149 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2160 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2163 Info.Note(SubobjectLoc, diag::note_constexpr_subobject_declared_here);
2170 Type = AT->getValueType();
2180 SubobjectLoc, CheckedTemps))
2197 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2198 unsigned BaseIndex = 0;
2202 BS.getBeginLoc(), CheckedTemps))
2207 for (
const auto *I : RD->
fields()) {
2208 if (I->isUnnamedBitfield())
2213 Usage, I->getLocation(), CheckedTemps))
2221 LVal.setFrom(Info.Ctx, Value);
2243 Info, DiagLoc, Type, Value, Usage,
2260 if (!Info.HeapAllocs.empty()) {
2264 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2265 diag::note_constexpr_memory_leak)
2266 <<
unsigned(Info.HeapAllocs.size() - 1);
2283 return !Decl || !Decl->
isWeak();
2292 Result = Val.
getInt().getBoolValue();
2321 llvm_unreachable(
"unknown APValue kind");
2326 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2333 template<
typename T>
2335 const T &SrcValue,
QualType DestType) {
2336 Info.CCEDiag(E, diag::note_constexpr_overflow)
2337 << SrcValue << DestType;
2338 return Info.noteUndefinedBehavior();
2342 QualType SrcType,
const APFloat &Value,
2344 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2348 Result =
APSInt(DestWidth, !DestSigned);
2350 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2351 & APFloat::opInvalidOp)
2361 Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
2362 APFloat::rmNearestTiesToEven, &ignored);
2369 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2372 APSInt Result = Value.extOrTrunc(DestWidth);
2381 QualType DestType, APFloat &Result) {
2382 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2383 Result.convertFromAPInt(Value, Value.isSigned(),
2384 APFloat::rmNearestTiesToEven);
2390 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2392 if (!Value.
isInt()) {
2396 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
2402 unsigned OldBitWidth = Int.getBitWidth();
2404 if (NewBitWidth < OldBitWidth)
2405 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2419 Res = SVal.
getFloat().bitcastToAPInt();
2424 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
2426 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
2427 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
2428 Res = llvm::APInt::getNullValue(VecSize);
2435 EltAsInt = Elt.
getFloat().bitcastToAPInt();
2439 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2442 unsigned BaseEltSize = EltAsInt.getBitWidth();
2444 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(i*EltSize+BaseEltSize);
2446 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(i*EltSize);
2452 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2459 template<
typename Operation>
2462 unsigned BitWidth, Operation Op,
2464 if (LHS.isUnsigned()) {
2465 Result = Op(LHS, RHS);
2469 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2470 Result = Value.trunc(LHS.getBitWidth());
2471 if (Result.extend(BitWidth) !=
Value) {
2472 if (Info.checkingForUndefinedBehavior())
2473 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2474 diag::warn_integer_constant_overflow)
2475 << Result.toString(10) << E->
getType();
2492 std::multiplies<APSInt>(), Result);
2495 std::plus<APSInt>(), Result);
2498 std::minus<APSInt>(), Result);
2499 case BO_And: Result = LHS & RHS;
return true;
2500 case BO_Xor: Result = LHS ^ RHS;
return true;
2501 case BO_Or: Result = LHS | RHS;
return true;
2505 Info.FFDiag(E, diag::note_expr_divide_by_zero);
2508 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2511 if (RHS.isNegative() && RHS.isAllOnesValue() &&
2512 LHS.isSigned() && LHS.isMinSignedValue())
2513 return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
2517 if (Info.getLangOpts().OpenCL)
2520 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2522 else if (RHS.isSigned() && RHS.isNegative()) {
2525 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2532 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2534 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2535 << RHS << E->
getType() << LHS.getBitWidth();
2536 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus2a) {
2541 if (LHS.isNegative())
2542 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2543 else if (LHS.countLeadingZeros() < SA)
2544 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2550 if (Info.getLangOpts().OpenCL)
2553 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2555 else if (RHS.isSigned() && RHS.isNegative()) {
2558 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2565 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2567 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2568 << RHS << E->
getType() << LHS.getBitWidth();
2573 case BO_LT: Result = LHS < RHS;
return true;
2574 case BO_GT: Result = LHS > RHS;
return true;
2575 case BO_LE: Result = LHS <= RHS;
return true;
2576 case BO_GE: Result = LHS >= RHS;
return true;
2577 case BO_EQ: Result = LHS == RHS;
return true;
2578 case BO_NE: Result = LHS != RHS;
return true;
2580 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2587 const APFloat &RHS) {
2593 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
2596 LHS.add(RHS, APFloat::rmNearestTiesToEven);
2599 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
2605 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2606 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
2615 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2616 return Info.noteUndefinedBehavior();
2625 unsigned TruncatedElements) {
2626 SubobjectDesignator &D = Result.Designator;
2629 if (TruncatedElements == D.Entries.size())
2631 assert(TruncatedElements >= D.MostDerivedPathLength &&
2632 "not casting to a derived class");
2638 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
2642 if (isVirtualBaseClass(D.Entries[I]))
2648 D.Entries.resize(TruncatedElements);
2658 RL = &Info.Ctx.getASTRecordLayout(Derived);
2661 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
2662 Obj.addDecl(Info, E, Base,
false);
2674 SubobjectDesignator &D = Obj.Designator;
2679 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
2685 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
2687 Obj.addDecl(Info, E, BaseDecl,
true);
2695 PathI != PathE; ++PathI) {
2699 Type = (*PathI)->getType();
2711 llvm_unreachable(
"Class must be derived from the passed in base class!");
2726 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
2730 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
2731 LVal.addDecl(Info, E, FD);
2739 for (
const auto *
C : IFD->
chain())
2767 Size = Info.Ctx.getTypeSizeInChars(Type);
2784 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
2790 int64_t Adjustment) {
2792 APSInt::get(Adjustment));
2807 LVal.Offset += SizeOfComponent;
2809 LVal.addComplex(Info, E, EltTy, Imag);
2822 const VarDecl *VD, CallStackFrame *Frame,
2823 APValue *&Result,
const LValue *LVal) {
2827 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
2830 if (Info.checkingPotentialConstantExpression())
2832 if (!Frame || !Frame->Arguments) {
2833 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2836 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
2842 Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion())
2843 : Frame->getCurrentTemporary(VD);
2851 "missing value for local variable");
2852 if (Info.checkingPotentialConstantExpression())
2856 diag::note_unimplemented_constexpr_lambda_feature_ast)
2857 <<
"captures not currently allowed";
2868 if (!Info.checkingPotentialConstantExpression())
2869 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2875 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
2876 Result = Info.EvaluatingDeclValue;
2883 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2891 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant,
2892 Notes.size() + 1) << VD;
2893 Info.Note(VD->
getLocation(), diag::note_declared_at);
2894 Info.addNotes(Notes);
2897 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2898 Notes.size() + 1) << VD;
2899 Info.Note(VD->
getLocation(), diag::note_declared_at);
2900 Info.addNotes(Notes);
2919 E = Derived->
bases_end(); I != E; ++I, ++Index) {
2920 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2924 llvm_unreachable(
"base class missing from derived class's bases list");
2930 assert(!isa<SourceLocExpr>(Lit) &&
2931 "SourceLocExpr should have already been converted to a StringLiteral");
2934 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
2936 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
2937 assert(Index <= Str.size() &&
"Index too large");
2938 return APSInt::getUnsigned(Str.c_str()[Index]);
2941 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2942 Lit = PE->getFunctionName();
2945 Info.Ctx.getAsConstantArrayType(S->
getType());
2946 assert(CAT &&
"string literal isn't an array");
2947 QualType CharType = CAT->getElementType();
2948 assert(CharType->
isIntegerType() &&
"unexpected character type");
2952 if (Index < S->getLength())
2965 AllocType.isNull() ? S->
getType() : AllocType);
2966 assert(CAT &&
"string literal isn't an array");
2968 assert(CharType->
isIntegerType() &&
"unexpected character type");
2970 unsigned Elts = CAT->
getSize().getZExtValue();
2986 assert(Index < Size);
2990 unsigned NewElts =
std::max(Index+1, OldElts * 2);
2995 for (
unsigned I = 0; I != OldElts; ++I)
2997 for (
unsigned I = OldElts; I != NewElts; ++I)
3001 Array.
swap(NewValue);
3016 for (
auto *Field : RD->
fields())
3020 for (
auto &BaseSpec : RD->
bases())
3038 for (
auto *Field : RD->
fields()) {
3043 if (Field->isMutable() &&
3045 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3046 Info.Note(Field->getLocation(), diag::note_declared_at);
3054 for (
auto &BaseSpec : RD->
bases())
3064 bool MutableSubobject =
false) {
3069 auto *Evaluating = Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>();
3075 switch (Info.IsEvaluatingDecl) {
3076 case EvalInfo::EvaluatingDeclKind::None:
3079 case EvalInfo::EvaluatingDeclKind::Ctor:
3087 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3091 case EvalInfo::EvaluatingDeclKind::Dtor:
3101 !(BaseD->getType().isConstQualified() ||
3102 BaseD->getType()->isReferenceType()) ||
3108 llvm_unreachable(
"unknown evaluating decl kind");
3114 struct CompleteObject {
3122 CompleteObject() :
Value(
nullptr) {}
3124 : Base(Base),
Value(Value), Type(Type) {}
3126 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
3130 if (!Info.getLangOpts().CPlusPlus14)
3135 explicit operator bool()
const {
return !Type.
isNull(); }
3140 bool IsMutable =
false) {
3154 template<
typename Sub
objectHandler>
3155 typename SubobjectHandler::result_type
3157 const SubobjectDesignator &
Sub, SubobjectHandler &handler) {
3160 return handler.failed();
3161 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
3162 if (Info.getLangOpts().CPlusPlus11)
3163 Info.FFDiag(E, Sub.isOnePastTheEnd()
3164 ? diag::note_constexpr_access_past_end
3165 : diag::note_constexpr_access_unsized_array)
3166 << handler.AccessKind;
3169 return handler.failed();
3175 const FieldDecl *VolatileField =
nullptr;
3178 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3184 if (!Info.checkingPotentialConstantExpression())
3185 Info.FFDiag(E, diag::note_constexpr_access_uninit)
3187 return handler.failed();
3195 Info.isEvaluatingCtorDtor(
3196 Obj.Base, llvm::makeArrayRef(Sub.Entries.begin(),
3197 Sub.Entries.begin() + I)) !=
3199 ObjType = Info.Ctx.getCanonicalType(ObjType);
3208 if (Info.getLangOpts().CPlusPlus) {
3212 if (VolatileField) {
3215 Decl = VolatileField;
3216 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3218 Loc = VD->getLocation();
3222 if (
auto *E = Obj.Base.dyn_cast<
const Expr *>())
3225 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3226 << handler.AccessKind << DiagKind << Decl;
3227 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
3229 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3231 return handler.failed();
3239 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
3241 return handler.failed();
3245 if (!handler.found(*O, ObjType))
3257 LastField =
nullptr;
3261 assert(CAT &&
"vla in literal type?");
3262 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3263 if (CAT->
getSize().ule(Index)) {
3266 if (Info.getLangOpts().CPlusPlus11)
3267 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3268 << handler.AccessKind;
3271 return handler.failed();
3278 else if (!
isRead(handler.AccessKind)) {
3285 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3287 if (Info.getLangOpts().CPlusPlus11)
3288 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3289 << handler.AccessKind;
3292 return handler.failed();
3298 assert(I == N - 1 &&
"extracting subobject of scalar?");
3307 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3308 if (Field->isMutable() &&
3309 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
3310 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
3311 << handler.AccessKind << Field;
3312 Info.Note(Field->getLocation(), diag::note_declared_at);
3313 return handler.failed();
3322 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
3330 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
3331 << handler.AccessKind << Field << !UnionField << UnionField;
3332 return handler.failed();
3341 if (Field->getType().isVolatileQualified())
3342 VolatileField = Field;
3355 struct ExtractSubobjectHandler {
3361 typedef bool result_type;
3362 bool failed() {
return false; }
3373 bool found(APFloat &Value,
QualType SubobjType) {
3382 const CompleteObject &Obj,
3383 const SubobjectDesignator &
Sub,
APValue &Result,
3386 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
3391 struct ModifySubobjectHandler {
3396 typedef bool result_type;
3402 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3408 bool failed() {
return false; }
3410 if (!checkConst(SubobjType))
3413 Subobj.
swap(NewVal);
3417 if (!checkConst(SubobjType))
3419 if (!NewVal.
isInt()) {
3427 bool found(APFloat &Value,
QualType SubobjType) {
3428 if (!checkConst(SubobjType))
3440 const CompleteObject &Obj,
3441 const SubobjectDesignator &
Sub,
3443 ModifySubobjectHandler Handler = { Info, NewVal, E };
3450 const SubobjectDesignator &A,
3451 const SubobjectDesignator &B,
3452 bool &WasArrayIndex) {
3453 unsigned I = 0, N =
std::min(A.Entries.size(), B.Entries.size());
3454 for (; I != N; ++I) {
3458 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
3459 WasArrayIndex =
true;
3467 if (A.Entries[I].getAsBaseOrMember() !=
3468 B.Entries[I].getAsBaseOrMember()) {
3469 WasArrayIndex =
false;
3472 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
3474 ObjType = FD->getType();
3480 WasArrayIndex =
false;
3487 const SubobjectDesignator &A,
3488 const SubobjectDesignator &B) {
3489 if (A.Entries.size() != B.Entries.size())
3492 bool IsArray = A.MostDerivedIsArrayElement;
3493 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
3502 return CommonLength >= A.Entries.size() - IsArray;
3509 if (LVal.InvalidBase) {
3511 return CompleteObject();
3515 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
3516 return CompleteObject();
3519 CallStackFrame *Frame =
nullptr;
3521 if (LVal.getLValueCallIndex()) {
3522 std::tie(Frame, Depth) =
3523 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
3525 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
3526 << AK << LVal.Base.is<
const ValueDecl*>();
3528 return CompleteObject();
3539 if (Info.getLangOpts().CPlusPlus)
3540 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
3544 return CompleteObject();
3549 QualType BaseType = getType(LVal.Base);
3566 return CompleteObject();
3572 if (Info.getLangOpts().CPlusPlus14 &&
3579 Info.FFDiag(E, diag::note_constexpr_modify_global);
3580 return CompleteObject();
3587 (Info.getLangOpts().OpenCL &&
3590 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3591 if (Info.getLangOpts().CPlusPlus) {
3592 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
3593 Info.Note(VD->
getLocation(), diag::note_declared_at);
3597 return CompleteObject();
3599 }
else if (!IsAccess) {
3600 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3605 if (Info.getLangOpts().CPlusPlus11) {
3606 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3607 Info.Note(VD->
getLocation(), diag::note_declared_at);
3612 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD;
3616 if (Info.checkingPotentialConstantExpression() &&
3620 }
else if (Info.getLangOpts().CPlusPlus11) {
3621 Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3622 Info.Note(VD->
getLocation(), diag::note_declared_at);
3626 return CompleteObject();
3631 return CompleteObject();
3635 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
3636 return CompleteObject();
3638 return CompleteObject(LVal.Base, &(*Alloc)->Value,
3639 LVal.Base.getDynamicAllocType());
3645 dyn_cast_or_null<MaterializeTemporaryExpr>(Base)) {
3646 assert(MTE->getStorageDuration() ==
SD_Static &&
3647 "should have a frame for a non-global materialized temporary");
3672 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3673 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
3674 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
3675 return CompleteObject();
3678 BaseVal = MTE->getOrCreateValue(
false);
3679 assert(BaseVal &&
"got reference to unevaluated temporary");
3682 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3685 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
3687 << Val.getAsString(Info.Ctx,
3688 Info.Ctx.getLValueReferenceType(LValType));
3690 return CompleteObject();
3693 BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion());
3694 assert(BaseVal &&
"missing value for temporary");
3703 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
3704 Info.EvalStatus.HasSideEffects) ||
3706 return CompleteObject();
3708 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
3727 const LValue &LVal,
APValue &RVal,
3728 bool WantObjectRepresentation =
false) {
3729 if (LVal.Designator.Invalid)
3748 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
3750 CompleteObject LitObj(LVal.Base, &Lit, Base->
getType());
3752 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
3755 assert(LVal.Designator.Entries.size() <= 1 &&
3756 "Can only read characters from string literals");
3757 if (LVal.Designator.Entries.empty()) {
3764 if (LVal.Designator.isOnePastTheEnd()) {
3765 if (Info.getLangOpts().CPlusPlus11)
3766 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
3771 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
3778 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
3784 if (LVal.Designator.Invalid)
3787 if (!Info.getLangOpts().CPlusPlus14) {
3797 struct CompoundAssignSubobjectHandler {
3806 typedef bool result_type;
3811 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3817 bool failed() {
return false; }
3821 return found(Subobj.
getInt(), SubobjType);
3823 return found(Subobj.
getFloat(), SubobjType);
3830 return foundPointer(Subobj, SubobjType);
3838 if (!checkConst(SubobjType))
3856 APFloat FValue(0.0);
3867 bool found(APFloat &Value,
QualType SubobjType) {
3868 return checkConst(SubobjType) &&
3875 if (!checkConst(SubobjType))
3883 (Opcode != BO_Add && Opcode != BO_Sub)) {
3889 if (Opcode == BO_Sub)
3893 LVal.setFrom(Info.Ctx, Subobj);
3896 LVal.moveInto(Subobj);
3906 EvalInfo &Info,
const Expr *E,
3909 if (LVal.Designator.Invalid)
3912 if (!Info.getLangOpts().CPlusPlus14) {
3918 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType,
Opcode,
3920 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3924 struct IncDecSubobjectHandler {
3930 typedef bool result_type;
3935 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3941 bool failed() {
return false; }
3952 return found(Subobj.
getInt(), SubobjType);
3954 return found(Subobj.
getFloat(), SubobjType);
3964 return foundPointer(Subobj, SubobjType);
3972 if (!checkConst(SubobjType))
3982 if (Old) *Old =
APValue(Value);
3994 bool WasNegative = Value.isNegative();
3998 if (!WasNegative && Value.isNegative() && E->
canOverflow()) {
3999 APSInt ActualValue(Value,
true);
4005 if (WasNegative && !Value.isNegative() && E->
canOverflow()) {
4006 unsigned BitWidth = Value.getBitWidth();
4007 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
4008 ActualValue.setBit(BitWidth);
4014 bool found(APFloat &Value,
QualType SubobjType) {
4015 if (!checkConst(SubobjType))
4018 if (Old) *Old =
APValue(Value);
4020 APFloat One(Value.getSemantics(), 1);
4022 Value.add(One, APFloat::rmNearestTiesToEven);
4024 Value.subtract(One, APFloat::rmNearestTiesToEven);
4028 if (!checkConst(SubobjType))
4040 LVal.setFrom(Info.Ctx, Subobj);
4044 LVal.moveInto(Subobj);
4053 if (LVal.Designator.Invalid)
4056 if (!Info.getLangOpts().CPlusPlus14) {
4063 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(E), AK, Old};
4064 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
4079 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
4098 bool IncludeMember =
true) {
4105 if (!MemPtr.getDecl()) {
4111 if (MemPtr.isDerivedMember()) {
4115 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
4116 LV.Designator.Entries.size()) {
4120 unsigned PathLengthToMember =
4121 LV.Designator.Entries.size() - MemPtr.Path.size();
4122 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
4124 LV.Designator.Entries[PathLengthToMember + I]);
4134 PathLengthToMember))
4136 }
else if (!MemPtr.Path.empty()) {
4138 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
4139 MemPtr.Path.size() + IncludeMember);
4145 assert(RD &&
"member pointer access on non-class-type expression");
4147 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
4155 MemPtr.getContainingRecord()))
4160 if (IncludeMember) {
4161 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
4165 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
4169 llvm_unreachable(
"can't construct reference to bound member function");
4173 return MemPtr.getDecl();
4179 bool IncludeMember =
true) {
4183 if (Info.noteFailure()) {
4191 BO->
getRHS(), IncludeMember);
4198 SubobjectDesignator &D = Result.Designator;
4199 if (D.Invalid || !Result.checkNullPointer(Info, E,
CSK_Derived))
4207 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
4208 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4209 << D.MostDerivedType << TargetQT;
4215 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
4218 if (NewEntriesSize == D.MostDerivedPathLength)
4219 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
4221 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
4223 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4224 << D.MostDerivedType << TargetQT;
4243 End = RD->bases_end(); I !=
End; ++I, ++Index)
4246 for (
const auto *I : RD->fields()) {
4247 if (I->isUnnamedBitfield())
4258 if (Array.hasArrayFiller())
4290 Info.CurrentCall->createTemporary(VD, VD->
getType(),
true,
Result);
4314 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
4318 for (
auto *BD : DD->bindings())
4319 if (
auto *VD = BD->getHoldingVar())
4328 const Expr *Cond,
bool &Result) {
4329 FullExpressionRAII
Scope(Info);
4334 return Scope.destroy();
4347 struct TempVersionRAII {
4348 CallStackFrame &Frame;
4350 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
4351 Frame.pushTempVersion();
4354 ~TempVersionRAII() {
4355 Frame.popTempVersion();
4369 BlockScopeRAII
Scope(Info);
4372 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !Scope.destroy())
4377 return ESR_Succeeded;
4380 return ESR_Continue;
4383 case ESR_CaseNotFound:
4386 llvm_unreachable(
"Invalid EvalStmtResult!");
4392 BlockScopeRAII
Scope(Info);
4399 if (ESR != ESR_Succeeded) {
4400 if (ESR != ESR_Failed && !Scope.destroy())
4406 FullExpressionRAII CondScope(Info);
4412 if (!CondScope.destroy())
4421 if (isa<DefaultStmt>(SC)) {
4426 const CaseStmt *CS = cast<CaseStmt>(SC);
4430 if (LHS <= Value && Value <= RHS) {
4437 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
4441 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !Scope.destroy())
4446 return ESR_Succeeded;
4452 case ESR_CaseNotFound:
4456 diag::note_constexpr_stmt_expr_unsupported);
4459 llvm_unreachable(
"Invalid EvalStmtResult!");
4465 if (!Info.nextStep(S))
4472 case Stmt::CompoundStmtClass:
4476 case Stmt::LabelStmtClass:
4477 case Stmt::AttributedStmtClass:
4478 case Stmt::DoStmtClass:
4481 case Stmt::CaseStmtClass:
4482 case Stmt::DefaultStmtClass:
4487 case Stmt::IfStmtClass: {
4490 const IfStmt *IS = cast<IfStmt>(S);
4494 BlockScopeRAII
Scope(Info);
4500 if (ESR != ESR_CaseNotFound) {
4501 assert(ESR != ESR_Succeeded);
4512 if (ESR == ESR_Failed)
4514 if (ESR != ESR_CaseNotFound)
4515 return Scope.destroy() ? ESR : ESR_Failed;
4517 return ESR_CaseNotFound;
4520 if (ESR == ESR_Failed)
4522 if (ESR != ESR_CaseNotFound)
4523 return Scope.destroy() ? ESR : ESR_Failed;
4524 return ESR_CaseNotFound;
4527 case Stmt::WhileStmtClass: {
4530 if (ESR != ESR_Continue)
4535 case Stmt::ForStmtClass: {
4536 const ForStmt *FS = cast<ForStmt>(S);
4537 BlockScopeRAII
Scope(Info);
4543 if (ESR != ESR_CaseNotFound) {
4544 assert(ESR != ESR_Succeeded);
4551 if (ESR != ESR_Continue)
4554 FullExpressionRAII IncScope(Info);
4561 case Stmt::DeclStmtClass: {
4564 const DeclStmt *DS = cast<DeclStmt>(S);
4565 for (
const auto *D : DS->
decls()) {
4566 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
4567 if (VD->hasLocalStorage() && !VD->getInit())
4575 return ESR_CaseNotFound;
4579 return ESR_CaseNotFound;
4585 if (
const Expr *E = dyn_cast<Expr>(S)) {
4590 FullExpressionRAII
Scope(Info);
4593 return ESR_Succeeded;
4599 case Stmt::NullStmtClass:
4600 return ESR_Succeeded;
4602 case Stmt::DeclStmtClass: {
4603 const DeclStmt *DS = cast<DeclStmt>(S);
4604 for (
const auto *D : DS->
decls()) {
4606 FullExpressionRAII
Scope(Info);
4609 if (!Scope.destroy())
4612 return ESR_Succeeded;
4615 case Stmt::ReturnStmtClass: {
4616 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
4617 FullExpressionRAII
Scope(Info);
4621 :
Evaluate(Result.Value, Info, RetExpr)))
4623 return Scope.destroy() ? ESR_Returned : ESR_Failed;
4626 case Stmt::CompoundStmtClass: {
4627 BlockScopeRAII
Scope(Info);
4630 for (
const auto *BI : CS->
body()) {
4632 if (ESR == ESR_Succeeded)
4634 else if (ESR != ESR_CaseNotFound) {
4635 if (ESR != ESR_Failed && !Scope.destroy())
4641 return ESR_CaseNotFound;
4642 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
4645 case Stmt::IfStmtClass: {
4646 const IfStmt *IS = cast<IfStmt>(S);
4649 BlockScopeRAII
Scope(Info);
4652 if (ESR != ESR_Succeeded) {
4653 if (ESR != ESR_Failed && !Scope.destroy())
4664 if (ESR != ESR_Succeeded) {
4665 if (ESR != ESR_Failed && !Scope.destroy())
4670 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
4673 case Stmt::WhileStmtClass: {
4674 const WhileStmt *WS = cast<WhileStmt>(S);
4676 BlockScopeRAII
Scope(Info);
4685 if (ESR != ESR_Continue) {
4686 if (ESR != ESR_Failed && !Scope.destroy())
4690 if (!Scope.destroy())
4693 return ESR_Succeeded;
4696 case Stmt::DoStmtClass: {
4697 const DoStmt *DS = cast<DoStmt>(S);
4701 if (ESR != ESR_Continue)
4705 FullExpressionRAII CondScope(Info);
4707 !CondScope.destroy())
4710 return ESR_Succeeded;
4713 case Stmt::ForStmtClass: {
4714 const ForStmt *FS = cast<ForStmt>(S);
4715 BlockScopeRAII ForScope(Info);
4718 if (ESR != ESR_Succeeded) {
4719 if (ESR != ESR_Failed && !ForScope.destroy())
4725 BlockScopeRAII IterScope(Info);
4726 bool Continue =
true;
4734 if (ESR != ESR_Continue) {
4735 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
4741 FullExpressionRAII IncScope(Info);
4746 if (!IterScope.destroy())
4749 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
4752 case Stmt::CXXForRangeStmtClass: {
4754 BlockScopeRAII
Scope(Info);
4759 if (ESR != ESR_Succeeded) {
4760 if (ESR != ESR_Failed && !Scope.destroy())
4768 if (ESR != ESR_Succeeded) {
4769 if (ESR != ESR_Failed && !Scope.destroy())
4776 if (ESR != ESR_Succeeded) {
4777 if (ESR != ESR_Failed && !Scope.destroy())
4782 if (ESR != ESR_Succeeded) {
4783 if (ESR != ESR_Failed && !Scope.destroy())
4791 bool Continue =
true;
4792 FullExpressionRAII CondExpr(Info);
4800 BlockScopeRAII InnerScope(Info);
4802 if (ESR != ESR_Succeeded) {
4803 if (ESR != ESR_Failed && (!InnerScope.destroy() || !Scope.destroy()))
4810 if (ESR != ESR_Continue) {
4811 if (ESR != ESR_Failed && (!InnerScope.destroy() || !Scope.destroy()))
4820 if (!InnerScope.destroy())
4824 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
4827 case Stmt::SwitchStmtClass:
4830 case Stmt::ContinueStmtClass:
4831 return ESR_Continue;
4833 case Stmt::BreakStmtClass:
4836 case Stmt::LabelStmtClass:
4837 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
4839 case Stmt::AttributedStmtClass:
4842 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
4845 case Stmt::CaseStmtClass:
4846 case Stmt::DefaultStmtClass:
4847 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
4848 case Stmt::CXXTryStmtClass:
4850 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
4860 bool IsValueInitialization) {
4867 if (!CD->
isConstexpr() && !IsValueInitialization) {
4868 if (Info.getLangOpts().CPlusPlus11) {
4871 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
4873 Info.Note(CD->
getLocation(), diag::note_declared_at);
4875 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
4889 if (Info.checkingPotentialConstantExpression() && !Definition &&
4897 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4904 if (!Info.Ctx.getLangOpts().CPlusPlus2a && isa<CXXMethodDecl>(Declaration) &&
4905 cast<CXXMethodDecl>(Declaration)->isVirtual())
4906 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
4909 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4914 if (Definition && Definition->
isConstexpr() && Body)
4917 if (Info.getLangOpts().CPlusPlus11) {
4918 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
4923 if (CD && CD->isInheritingConstructor()) {
4925 if (!Inherited->isConstexpr())
4926 DiagDecl = CD = Inherited;
4932 if (CD && CD->isInheritingConstructor())
4933 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
4934 << CD->getInheritedConstructor().getConstructor()->getParent();
4936 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
4938 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
4940 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4946 struct CheckDynamicTypeHandler {
4948 typedef bool result_type;
4949 bool failed() {
return false; }
4952 bool found(APFloat &Value,
QualType SubobjType) {
return true; }
4960 if (This.Designator.Invalid)
4972 if (This.Designator.isOnePastTheEnd() ||
4973 This.Designator.isMostDerivedAnUnsizedArray()) {
4974 Info.FFDiag(E, This.Designator.isOnePastTheEnd()
4975 ? diag::note_constexpr_access_past_end
4976 : diag::note_constexpr_access_unsized_array)
4979 }
else if (Polymorphic) {
4985 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
4986 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
4993 CheckDynamicTypeHandler Handler{AK};
4994 return Obj &&
findSubobject(Info, E, Obj, This.Designator, Handler);
5016 unsigned PathLength) {
5017 assert(PathLength >= Designator.MostDerivedPathLength && PathLength <=
5018 Designator.Entries.size() &&
"invalid path length");
5019 return (PathLength == Designator.MostDerivedPathLength)
5020 ? Designator.MostDerivedType->getAsCXXRecordDecl()
5021 : getAsBaseClass(Designator.Entries[PathLength - 1]);
5040 This.Designator.MostDerivedType->getAsCXXRecordDecl();
5051 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
5052 PathLength <= Path.size(); ++PathLength) {
5053 switch (Info.isEvaluatingCtorDtor(This.getLValueBase(),
5054 Path.slice(0, PathLength))) {
5055 case ConstructionPhase::Bases:
5056 case ConstructionPhase::DestroyingBases:
5062 case ConstructionPhase::AfterBases:
5063 case ConstructionPhase::Destroying:
5093 unsigned PathLength = DynType->PathLength;
5094 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
5108 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
5109 Info.Note(Callee->
getLocation(), diag::note_declared_at);
5115 if (!Info.Ctx.hasSameUnqualifiedType(Callee->
getReturnType(),
5118 for (
unsigned CovariantPathLength = PathLength + 1;
5119 CovariantPathLength != This.Designator.Entries.size();
5120 ++CovariantPathLength) {
5125 if (Next && !Info.Ctx.hasSameUnqualifiedType(
5129 if (!Info.Ctx.hasSameUnqualifiedType(Found->
getReturnType(),
5130 CovariantAdjustmentPath.back()))
5148 "unexpected kind of APValue for covariant return");
5153 LVal.setFrom(Info.Ctx, Result);
5155 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
5156 for (
unsigned I = 1; I != Path.size(); ++I) {
5157 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
5158 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
5159 if (OldClass != NewClass &&
5162 OldClass = NewClass;
5165 LVal.moveInto(Result);
5174 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
5176 return BaseSpec.getAccessSpecifier() ==
AS_public;
5178 llvm_unreachable(
"Base is not a direct base of Derived");
5188 SubobjectDesignator &D = Ptr.Designator;
5194 if (Ptr.isNullPointer() && !E->
isGLValue())
5212 assert(C &&
"dynamic_cast target is not void pointer nor class");
5213 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(C));
5220 Ptr.setNull(Info.Ctx, E->
getType());
5227 DynType->Type->isDerivedFrom(C)))
5229 else if (!Paths || Paths->begin() == Paths->end())
5231 else if (Paths->isAmbiguous(CQT))
5234 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
5237 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
5238 << DiagKind << Ptr.Designator.getType(Info.Ctx)
5239 << Info.Ctx.getRecordType(DynType->Type)
5247 for (
int PathLength = Ptr.Designator.Entries.size();
5248 PathLength >= (int)DynType->PathLength; --PathLength) {
5253 if (PathLength > (
int)DynType->PathLength &&
5256 return RuntimeCheckFailed(
nullptr);
5263 if (DynType->Type->isDerivedFrom(C, Paths) && !Paths.
isAmbiguous(CQT) &&
5276 return RuntimeCheckFailed(&Paths);
5280 struct StartLifetimeOfUnionMemberHandler {
5285 typedef bool result_type;
5286 bool failed() {
return false; }
5303 llvm_unreachable(
"wrong value kind for union object");
5305 bool found(APFloat &Value,
QualType SubobjType) {
5306 llvm_unreachable(
"wrong value kind for union object");
5318 const LValue &LHS) {
5319 if (LHS.InvalidBase || LHS.Designator.Invalid)
5325 unsigned PathLength = LHS.Designator.Entries.size();
5326 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
5328 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
5329 auto *FD = dyn_cast<
FieldDecl>(ME->getMemberDecl());
5332 if (!FD || FD->getType()->isReferenceType())
5336 if (FD->getParent()->isUnion()) {
5342 if (!RD || RD->hasTrivialDefaultConstructor())
5343 UnionPathLengths.push_back({PathLength - 1, FD});
5349 LHS.Designator.Entries[PathLength]
5350 .getAsBaseOrMember().getPointer()));
5354 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
5356 auto *
Base = ASE->getBase()->IgnoreImplicit();
5357 if (!
Base->getType()->isArrayType())
5363 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
5365 E = ICE->getSubExpr();
5366 if (ICE->getCastKind() == CK_NoOp)
5368 if (ICE->getCastKind() != CK_DerivedToBase &&
5369 ICE->getCastKind() != CK_UncheckedDerivedToBase)
5376 LHS.Designator.Entries[PathLength]
5377 .getAsBaseOrMember().getPointer()));
5387 if (UnionPathLengths.empty())
5392 CompleteObject Obj =
5396 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
5397 llvm::reverse(UnionPathLengths)) {
5399 SubobjectDesignator D = LHS.Designator;
5400 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
5402 StartLifetimeOfUnionMemberHandler StartLifetime{LengthAndField.second};
5415 for (
auto *FD : RD->
fields()) {
5416 if (FD->isUnnamedBitfield())
5433 bool Success =
true;
5434 llvm::SmallBitVector ForbiddenNullArgs;
5435 if (Callee->
hasAttr<NonNullAttr>()) {
5436 ForbiddenNullArgs.resize(Args.size());
5438 if (!
Attr->args_size()) {
5439 ForbiddenNullArgs.set();
5442 for (
auto Idx :
Attr->args()) {
5443 unsigned ASTIdx = Idx.getASTIndex();
5444 if (ASTIdx >= Args.size())
5446 ForbiddenNullArgs[ASTIdx] = 1;
5450 for (
unsigned Idx = 0; Idx < Args.size(); Idx++) {
5451 if (!
Evaluate(ArgValues[Idx], Info, Args[Idx])) {
5454 if (!Info.noteFailure())
5457 }
else if (!ForbiddenNullArgs.empty() &&
5458 ForbiddenNullArgs[Idx] &&
5459 ArgValues[Idx].isLValue() &&
5460 ArgValues[Idx].isNullPointer()) {
5461 Info.CCEDiag(Args[Idx], diag::note_non_null_attribute_failed);
5462 if (!Info.noteFailure())
5474 EvalInfo &Info,
APValue &Result,
5475 const LValue *ResultSlot) {
5476 ArgVector ArgValues(Args.size());
5480 if (!Info.CheckCallLimit(CallLoc))
5483 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
5492 if (MD && MD->isDefaulted() &&
5493 (MD->getParent()->isUnion() ||
5494 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
5496 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
5498 RHS.setFrom(Info.Ctx, ArgValues[0]);
5501 RHSValue, MD->getParent()->
isUnion()))
5503 if (Info.getLangOpts().CPlusPlus2a && MD->isTrivial() &&
5509 This->moveInto(Result);
5518 if (!Info.checkingPotentialConstantExpression())
5519 MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
5520 Frame.LambdaThisCaptureField);
5525 if (ESR == ESR_Succeeded) {
5528 Info.FFDiag(Callee->
getEndLoc(), diag::note_constexpr_no_return);
5530 return ESR == ESR_Returned;
5537 EvalInfo &Info,
APValue &Result) {
5539 if (!Info.CheckCallLimit(CallLoc))
5544 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
5548 EvalInfo::EvaluatingConstructorRAII EvalObj(
5550 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
5552 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
5563 FullExpressionRAII InitScope(Info);
5565 !InitScope.destroy())
5583 RHS.setFrom(Info.Ctx, ArgValues[0]);
5598 BlockScopeRAII LifetimeExtendedScope(Info);
5600 bool Success =
true;
5601 unsigned BasesSeen = 0;
5606 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
5611 assert(Indirect &&
"fields out of order?");
5617 assert(FieldIt != RD->
field_end() &&
"missing field?");
5618 if (!FieldIt->isUnnamedBitfield())
5624 for (
const auto *I : Definition->
inits()) {
5625 LValue Subobject =
This;
5626 LValue SubobjectParent =
This;
5631 if (I->isBaseInitializer()) {
5632 QualType BaseType(I->getBaseClass(), 0);
5636 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
5637 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
5638 "base class initializers not in expected order");
5642 BaseType->getAsCXXRecordDecl(), &Layout))
5645 }
else if ((FD = I->getMember())) {
5652 SkipToField(FD,
false);
5658 auto IndirectFieldChain = IFD->chain();
5659 for (
auto *
C : IndirectFieldChain) {
5660 FD = cast<FieldDecl>(
C);
5679 if (
C == IndirectFieldChain.back())
5680 SubobjectParent = Subobject;
5686 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
5687 SkipToField(FD,
true);
5692 llvm_unreachable(
"unknown base initializer kind");
5698 const Expr *Init = I->getInit();
5699 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
5700 isa<CXXDefaultInitExpr>(Init));
5701 FullExpressionRAII InitScope(Info);
5707 if (!Info.noteFailure())
5714 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
5715 EvalObj.finishedConstructingBases();
5720 for (; FieldIt != RD->
field_end(); ++FieldIt) {
5721 if (!FieldIt->isUnnamedBitfield())
5729 LifetimeExtendedScope.destroy();
5735 EvalInfo &Info,
APValue &Result) {
5736 ArgVector ArgValues(Args.size());
5745 const LValue &This,
APValue &Value,
5753 This.moveInto(Printable);
5754 Info.FFDiag(CallLoc, diag::note_constexpr_destroy_out_of_lifetime)
5755 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(T));
5765 uint64_t Size = CAT->getSize().getZExtValue();
5766 QualType ElemT = CAT->getElementType();
5768 LValue ElemLV =
This;
5769 ElemLV.addArray(Info, &LocE, CAT);
5779 for (; Size != 0; --Size) {
5794 Info.FFDiag(CallLoc, diag::note_constexpr_unsupported_destruction) << T;
5803 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
5809 Info.FFDiag(CallLoc);
5828 if (!Info.CheckCallLimit(CallLoc))
5837 CallStackFrame Frame(Info, CallLoc, Definition, &This,
nullptr);
5841 EvalInfo::EvaluatingDestructorRAII EvalObj(
5843 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries});
5844 if (!EvalObj.DidInsert) {
5851 Info.FFDiag(CallLoc, diag::note_constexpr_double_destroy);
5871 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
5872 if (FD->isUnnamedBitfield())
5875 LValue Subobject =
This;
5886 EvalObj.startedDestroyingBases();
5893 LValue Subobject =
This;
5903 assert(BasesLeft == 0 &&
"NumBases was wrong?");
5911 struct DestroyObjectHandler {
5917 typedef bool result_type;
5918 bool failed() {
return false; }
5924 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
5927 bool found(APFloat &Value,
QualType SubobjType) {
5928 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
5937 const LValue &This,
QualType ThisType) {
5940 return Obj &&
findSubobject(Info, E, Obj, This.Designator, Handler);
5949 if (Info.EvalStatus.HasSideEffects)
5960 if (Info.checkingPotentialConstantExpression() ||
5961 Info.SpeculativeEvaluationDepth)
5965 auto Caller = Info.getStdAllocatorCaller(
"allocate");
5967 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus2a
5968 ? diag::note_constexpr_new_untyped
5969 : diag::note_constexpr_new);
5973 QualType ElemType = Caller.ElemType;
5976 diag::note_constexpr_new_not_complete_object_type)
5984 bool IsNothrow =
false;
5985 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
5993 APInt Size, Remainder;
5995 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
5996 if (Remainder != 0) {
5998 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
5999 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
6005 Result.setNull(Info.Ctx, E->
getType());
6009 Info.FFDiag(E, diag::note_constexpr_new_too_large) <<
APSInt(Size,
true);
6013 QualType AllocType = Info.Ctx.getConstantArrayType(ElemType, Size,
nullptr,
6015 APValue *Val = Info.createHeapAlloc(E, AllocType, Result);
6017 Result.addArray(Info, E, cast<ConstantArrayType>(AllocType));
6024 return DD->isVirtual();
6031 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
6041 const LValue &Pointer,
6042 DynAlloc::Kind DeallocKind) {
6043 auto PointerAsString = [&] {
6044 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
6049 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
6050 << PointerAsString();
6058 Info.FFDiag(E, diag::note_constexpr_double_delete);
6062 QualType AllocType = Pointer.Base.getDynamicAllocType();
6063 if (DeallocKind != (*Alloc)->getKind()) {
6064 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
6065 << DeallocKind << (*Alloc)->getKind() << AllocType;
6070 bool Subobject =
false;
6071 if (DeallocKind == DynAlloc::New) {
6072 Subobject = Pointer.Designator.MostDerivedPathLength != 0 ||
6073 Pointer.Designator.isOnePastTheEnd();
6075 Subobject = Pointer.Designator.Entries.size() != 1 ||
6076 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
6079 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
6080 << PointerAsString() << Pointer.Designator.isOnePastTheEnd();
6089 if (Info.checkingPotentialConstantExpression() ||
6090 Info.SpeculativeEvaluationDepth)
6094 if (!Info.getStdAllocatorCaller(
"deallocate")) {
6102 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
6105 if (Pointer.Designator.Invalid)
6109 if (Pointer.isNullPointer())
6124 class BitCastBuffer {
6132 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
6133 "Need at least 8 bit unsigned char");
6135 bool TargetIsLittleEndian;
6138 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
6140 TargetIsLittleEndian(TargetIsLittleEndian) {}
6145 for (
CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
6148 if (!Bytes[I.getQuantity()])
6150 Output.push_back(*Bytes[I.getQuantity()]);
6152 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
6153 std::reverse(Output.begin(), Output.end());
6158 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
6159 std::reverse(Input.begin(), Input.end());
6162 for (
unsigned char Byte : Input) {
6163 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
6169 size_t size() {
return Bytes.size(); }
6174 class APValueToBufferConverter {
6176 BitCastBuffer Buffer;
6179 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
6182 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
6191 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
6208 return visitArray(Val, Ty, Offset);
6210 return visitRecord(Val, Ty, Offset);
6222 diag::note_constexpr_bit_cast_unsupported_type)
6228 llvm_unreachable(
"LValue subobject in bit_cast?");
6230 llvm_unreachable(
"Unhandled APValue::ValueKind");
6238 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
6239 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
6250 unsigned FieldIdx = 0;
6252 if (FD->isBitField()) {
6254 diag::note_constexpr_bit_cast_unsupported_bitfield);
6260 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
6261 "only bit-fields can have sub-char alignment");
6263 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) +
Offset;
6279 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->getElementType());
6283 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
6285 if (!visit(SubObj, CAT->getElementType(), Offset + I * ElemWidth))
6292 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
6293 if (!visit(Filler, CAT->getElementType(), Offset + I * ElemWidth))
6302 CharUnits Width = Info.Ctx.getTypeSizeInChars(Ty);
6304 llvm::StoreIntToMemory(Val, &*Bytes.begin(), Width.
getQuantity());
6305 Buffer.writeObject(Offset, Bytes);
6310 APSInt AsInt(Val.bitcastToAPInt());
6311 return visitInt(AsInt, Ty, Offset);
6318 APValueToBufferConverter Converter(Info, DstSize, BCE);
6321 return Converter.Buffer;
6326 class BufferToAPValueConverter {
6328 const BitCastBuffer &Buffer;
6331 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
6333 : Info(Info), Buffer(Buffer), BCE(BCE) {}
6338 llvm::NoneType unsupportedType(
QualType Ty) {
6340 diag::note_constexpr_bit_cast_unsupported_type)
6346 const EnumType *EnumSugar =
nullptr) {
6348 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(
QualType(T, 0));
6354 CharUnits SizeOf = Info.Ctx.getTypeSizeInChars(T);
6356 if (!Buffer.readObject(Offset, SizeOf, Bytes)) {
6359 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
6363 if (!IsStdByte && !IsUChar) {
6364 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
6366 diag::note_constexpr_bit_cast_indet_dest)
6367 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
6374 APSInt Val(SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
6375 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
6383 const llvm::fltSemantics &Semantics =
6384 Info.Ctx.getFloatTypeSemantics(
QualType(T, 0));
6385 return APValue(APFloat(Semantics, Val));
6388 return unsupportedType(
QualType(T, 0));
6395 unsigned NumBases = 0;
6396 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
6397 NumBases = CXXRD->getNumBases();
6403 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
6404 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
6408 Info.Ctx.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero())
6420 unsigned FieldIdx = 0;
6424 if (FD->isBitField()) {
6426 diag::note_constexpr_bit_cast_unsupported_bitfield);
6431 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
6449 assert(!RepresentationType.
isNull() &&
6450 "enum forward decl should be caught by Sema");
6451 const auto *AsBuiltin =
6455 return visit(AsBuiltin, Offset, Ty);
6459 size_t Size = Ty->
getSize().getLimitedValue();
6463 for (
size_t I = 0; I != Size; ++I) {
6475 return unsupportedType(
QualType(Ty, 0));
6482 #define TYPE(Class, Base) \ 6484 return visit(cast<Class##Type>(Can.getTypePtr()), Offset); 6485 #define ABSTRACT_TYPE(Class, Base) 6486 #define NON_CANONICAL_TYPE(Class, Base) \ 6488 llvm_unreachable("non-canonical type should be impossible!"); 6489 #define DEPENDENT_TYPE(Class, Base) \ 6492 "dependent types aren't supported in the constant evaluator!"); 6493 #define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \ 6495 llvm_unreachable("either dependent or not canonical!"); 6496 #include "clang/AST/TypeNodes.inc" 6498 llvm_unreachable(
"Unhandled Type::TypeClass");
6505 BufferToAPValueConverter Converter(Info, Buffer, BCE);
6510 static bool checkBitCastConstexprEligibilityType(
SourceLocation Loc,
6513 bool CheckingDest) {
6516 auto diag = [&](
int Reason) {
6518 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
6519 << CheckingDest << (Reason == 4) << Reason;
6524 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
6525 << NoteTy << Construct << Ty;
6539 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(Record)) {
6541 if (!checkBitCastConstexprEligibilityType(Loc, BS.getType(), Info, Ctx,
6543 return note(1, BS.getType(), BS.getBeginLoc());
6545 for (
FieldDecl *FD : Record->fields()) {
6546 if (FD->getType()->isReferenceType())
6548 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
6550 return note(0, FD->getType(), FD->getBeginLoc());
6556 Info, Ctx, CheckingDest))
6562 static bool checkBitCastConstexprEligibility(EvalInfo *Info,
6565 bool DestOK = checkBitCastConstexprEligibilityType(
6567 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
6573 static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
6576 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
6577 "no host or target supports non 8-bit chars");
6579 "LValueToRValueBitcast requires an lvalue operand!");
6581 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
6584 LValue SourceLValue;
6586 SourceLValue.setFrom(Info.Ctx, SourceValue);
6589 SourceRValue,
true))
6594 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
6600 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
6601 if (!MaybeDestValue)
6604 DestValue = std::move(*MaybeDestValue);
6608 template <
class Derived>
6609 class ExprEvaluatorBase
6612 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
6614 return getDerived().Success(V, E);
6616 bool DerivedZeroInitialization(
const Expr *E) {
6617 return getDerived().ZeroInitialization(E);
6623 template<
typename ConditionalOperator>
6625 assert(Info.checkingPotentialConstantExpression());
6630 SpeculativeEvaluationRAII Speculate(Info, &Diag);
6637 SpeculativeEvaluationRAII Speculate(Info, &Diag);
6644 Error(E, diag::note_constexpr_conditional_never_const);
6648 template<
typename ConditionalOperator>
6652 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
6653 CheckPotentialConstantConditional(E);
6656 if (Info.noteFailure()) {
6664 return StmtVisitorTy::Visit(EvalExpr);
6670 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
6673 return Info.CCEDiag(E, D);
6676 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
6679 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
6681 EvalInfo &getEvalInfo() {
return Info; }
6690 return Error(E, diag::note_invalid_subexpr_in_const_expr);
6693 bool VisitStmt(
const Stmt *) {
6694 llvm_unreachable(
"Expression evaluator should not be called on stmts");
6696 bool VisitExpr(
const Expr *E) {
6701 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
6703 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
6705 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
6707 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
6715 TempVersionRAII RAII(*Info.CurrentCall);
6716 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
6717 return StmtVisitorTy::Visit(E->
getExpr());
6720 TempVersionRAII RAII(*Info.CurrentCall);
6724 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
6725 return StmtVisitorTy::Visit(E->
getExpr());
6729 FullExpressionRAII
Scope(Info);
6730 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
6736 return StmtVisitorTy::Visit(E->
getSubExpr());
6740 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
6741 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
6744 if (!Info.Ctx.getLangOpts().CPlusPlus2a)
6745 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
6746 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
6749 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
6758 VisitIgnoredValue(E->
getLHS());
6759 return StmtVisitorTy::Visit(E->
getRHS());
6769 return DerivedSuccess(Result, E);
6782 if (!
Evaluate(Info.CurrentCall->createTemporary(
6789 return HandleConditionalOperator(E);
6793 bool IsBcpCall =
false;
6800 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
6807 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
6810 FoldConstant Fold(Info, IsBcpCall);
6811 if (!HandleConditionalOperator(E)) {
6812 Fold.keepDiagnostics();
6820 if (
APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
6821 return DerivedSuccess(*Value, E);
6827 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
6830 return StmtVisitorTy::Visit(Source);
6835 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
6844 if (OVE->isUnique())
6848 if (!
Evaluate(Info.CurrentCall->createTemporary(
6849 OVE, getStorageType(Info.Ctx, OVE),
false, LV),
6850 Info, OVE->getSourceExpr()))
6853 if (!StmtVisitorTy::Visit(SemE))
6863 bool VisitCallExpr(
const CallExpr *E) {
6865 if (!handleCallExpr(E, Result,
nullptr))
6867 return DerivedSuccess(Result, E);
6871 const LValue *ResultSlot) {
6876 LValue *This =
nullptr, ThisVal;
6878 bool HasQualifier =
false;
6883 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
6889 return Error(Callee);
6891 HasQualifier = ME->hasQualifier();
6892 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
6900 return Error(Callee);
6902 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
6903 if (!Info.getLangOpts().CPlusPlus2a)
6904 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
6910 return Error(Callee);
6917 if (!Call.getLValueOffset().isZero())
6918 return Error(Callee);
6919 FD = dyn_cast_or_null<FunctionDecl>(
6920 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
6922 return Error(Callee);
6925 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
6943 Args = Args.slice(1);
6952 "Number of captures must be zero for conversion to function-ptr");
6963 "A generic lambda's static-invoker function must be a " 6964 "template specialization");
6967 LambdaCallOp->getDescribedFunctionTemplate();
6968 void *InsertPos =
nullptr;
6971 assert(CorrespondingCallOpSpecialization &&
6972 "We must always have a function call operator specialization " 6973 "that corresponds to our static invoker specialization");
6974 FD = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
6983 Ptr.moveInto(Result);
6995 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
6998 CovariantAdjustmentPath);
7011 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
7012 assert(This &&
"no 'this' pointer for destructor call");
7014 Info.Ctx.getRecordType(DD->getParent()));
7025 if (!CovariantAdjustmentPath.empty() &&
7027 CovariantAdjustmentPath))
7038 return DerivedZeroInitialization(E);
7040 return StmtVisitorTy::Visit(E->
getInit(0));
7044 return DerivedZeroInitialization(E);
7047 return DerivedZeroInitialization(E);
7050 return DerivedZeroInitialization(E);
7055 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
7056 "missing temporary materialization conversion");
7057 assert(!E->
isArrow() &&
"missing call to bound member function?");
7066 if (!FD)
return Error(E);
7076 Designator.addDeclUnchecked(FD);
7080 DerivedSuccess(Result, E);
7091 if (Indices.size() == 1) {
7093 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
7097 for (
unsigned I = 0; I < Indices.size(); ++I) {
7100 APValue VecResult(Elts.data(), Indices.size());
7101 return DerivedSuccess(VecResult, E);
7108 bool VisitCastExpr(
const CastExpr *E) {
7113 case CK_AtomicToNonAtomic: {
7120 return DerivedSuccess(AtomicVal, E);
7124 case CK_UserDefinedConversion:
7125 return StmtVisitorTy::Visit(E->
getSubExpr());
7127 case CK_LValueToRValue: {
7136 return DerivedSuccess(RVal, E);
7138 case CK_LValueToRValueBitCast: {
7139 APValue DestValue, SourceValue;
7142 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
7144 return DerivedSuccess(DestValue, E);
7147 case CK_AddressSpaceConversion: {
7151 return DerivedSuccess(Value, E);
7159 return VisitUnaryPostIncDec(UO);
7162 return VisitUnaryPostIncDec(UO);
7165 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
7175 return DerivedSuccess(RVal, UO);
7178 bool VisitStmtExpr(
const StmtExpr *E) {
7181 if (Info.checkingForUndefinedBehavior())
7188 BlockScopeRAII
Scope(Info);
7193 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
7195 Info.FFDiag((*BI)->getBeginLoc(),
7196 diag::note_constexpr_stmt_expr_unsupported);
7199 return this->Visit(FinalExpr) && Scope.destroy();
7205 if (ESR != ESR_Succeeded) {
7209 if (ESR != ESR_Failed)
7210 Info.FFDiag((*BI)->getBeginLoc(),
7211 diag::note_constexpr_stmt_expr_unsupported);
7216 llvm_unreachable(
"Return from function from the loop above.");
7220 void VisitIgnoredValue(
const Expr *E) {
7225 void VisitIgnoredBaseExpression(
const Expr *E) {
7228 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
7230 VisitIgnoredValue(E);
7240 template<
class Derived>
7241 class LValueExprEvaluatorBase
7242 :
public ExprEvaluatorBase<Derived> {
7246 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
7247 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
7254 bool evaluatePointer(
const Expr *E, LValue &Result) {
7259 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
7260 : ExprEvaluatorBaseTy(Info),
Result(Result),
7261 InvalidBaseOK(InvalidBaseOK) {}
7264 Result.setFrom(this->Info.Ctx, V);
7280 EvalOK = this->Visit(E->
getBase());
7286 Result.setInvalid(E);
7293 FD->
getParent()->getCanonicalDecl() &&
"record / field mismatch");
7301 return this->
Error(E);
7308 return Success(RefValue, E);
7316 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7324 bool VisitCastExpr(
const CastExpr *E) {
7327 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7329 case CK_DerivedToBase:
7330 case CK_UncheckedDerivedToBase:
7375 class LValueExprEvaluator
7376 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
7378 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
7379 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
7381 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
7385 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
7389 bool VisitStringLiteral(
const StringLiteral *E) {
return Success(E); }
7390 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
7398 return VisitUnaryPreIncDec(UO);
7401 return VisitUnaryPreIncDec(UO);
7406 bool VisitCastExpr(
const CastExpr *E) {
7409 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
7411 case CK_LValueBitCast:
7412 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
7415 Result.Designator.setInvalid();
7418 case CK_BaseToDerived:
7438 bool InvalidBaseOK) {
7441 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
7444 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
7448 return VisitVarDecl(E, VD);
7450 return Visit(BD->getBinding());
7455 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
7462 isa<DeclRefExpr>(E) &&
7463 cast<DeclRefExpr>(E)->refersToEnclosingVariableOrCapture()) {
7468 if (Info.checkingPotentialConstantExpression())
7471 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
7473 Result = *Info.CurrentCall->This;
7480 if (FD->getType()->isReferenceType()) {
7485 Result.setFrom(Info.Ctx, RVal);
7490 CallStackFrame *Frame =
nullptr;
7498 if (Info.CurrentCall->Callee &&
7500 Frame = Info.CurrentCall;
7506 Result.set({VD, Frame->Index,
7507 Info.CurrentCall->getCurrentTemporaryVersion(VD)});
7519 if (!Info.checkingPotentialConstantExpression())
7520 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
7523 return Success(*V, E);
7526 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
7535 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
7548 Value = &Info.CurrentCall->createTemporary(
7561 for (
unsigned I = Adjustments.size(); I != 0; ) {
7563 switch (Adjustments[I].
Kind) {
7568 Type = Adjustments[I].DerivedToBase.BasePath->getType();
7574 Type = Adjustments[I].Field->getType();
7579 Adjustments[I].Ptr.RHS))
7581 Type = Adjustments[I].Ptr.MPT->getPointeeType();
7591 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
7592 "lvalue compound literal in c++?");
7598 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
7607 if (!Info.Ctx.getLangOpts().CPlusPlus2a) {
7608 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
7622 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
7628 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
7632 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
7635 VisitIgnoredBaseExpression(E->
getBase());
7636 return VisitVarDecl(E, VD);
7641 if (MD->isStatic()) {
7642 VisitIgnoredBaseExpression(E->
getBase());
7648 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
7656 bool Success =
true;
7658 if (!Info.noteFailure())
7671 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
7675 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
7684 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
7686 "lvalue __imag__ on scalar?");
7693 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
7694 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
7705 bool LValueExprEvaluator::VisitCompoundAssignOperator(
7707 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
7713 if (!this->Visit(CAO->
getLHS())) {
7714 if (Info.noteFailure())
7728 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
7729 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
7734 if (!this->Visit(E->
getLHS())) {
7735 if (Info.noteFailure())
7743 if (Info.getLangOpts().CPlusPlus2a &&
7764 const AllocSizeAttr *AllocSize = getAllocSizeAttr(Call);
7766 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
7767 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
7772 auto EvaluateAsSizeT = [&](
const Expr *E,
APSInt &Into) {
7777 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
7779 Into = Into.zextOrSelf(BitsInSizeT);
7784 if (!EvaluateAsSizeT(Call->
getArg(SizeArgNo), SizeOfElem))
7787 if (!AllocSize->getNumElemsParam().isValid()) {
7788 Result = std::move(SizeOfElem);
7793 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
7794 if (!EvaluateAsSizeT(Call->
getArg(NumArgNo), NumberOfElems))
7798 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
7802 Result = std::move(BytesAvailable);
7811 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
7812 "Can't get the size of a non alloc_size function");
7813 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
7842 if (!tryUnwrapAllocSizeCall(E))
7847 Result.setInvalid(E);
7850 Result.addUnsizedArray(Info, E, Pointee);
7855 class PointerExprEvaluator
7856 :
public ExprEvaluatorBase<PointerExprEvaluator> {
7860 bool Success(
const Expr *E) {
7865 bool evaluateLValue(
const Expr *E, LValue &Result) {
7869 bool evaluatePointer(
const Expr *E, LValue &Result) {
7873 bool visitNonBuiltinCallExpr(
const CallExpr *E);
7876 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
7877 : ExprEvaluatorBaseTy(info),
Result(Result),
7878 InvalidBaseOK(InvalidBaseOK) {}
7881 Result.setFrom(Info.Ctx, V);
7884 bool ZeroInitialization(
const Expr *E) {
7885 Result.setNull(Info.Ctx, E->
getType());
7890 bool VisitCastExpr(
const CastExpr* E);
7893 {
return Success(E); }
7897 if (Info.noteFailure())
7902 {
return Success(E); }
7903 bool VisitCallExpr(
const CallExpr *E);
7904 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
7905 bool VisitBlockExpr(
const BlockExpr *E) {
7912 if (Info.checkingPotentialConstantExpression())
7914 if (!Info.CurrentCall->This) {
7915 if (Info.getLangOpts().CPlusPlus11)
7916 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
7921 Result = *Info.CurrentCall->This;
7929 if (!Info.CurrentCall->LambdaThisCaptureField)
7935 Info.CurrentCall->LambdaThisCaptureField))
7938 if (Info.CurrentCall->LambdaThisCaptureField->getType()
7939 ->isPointerType()) {
7945 Result.setFrom(Info.Ctx, RVal);
7954 assert(E->
isStringType() &&
"SourceLocExpr isn't a pointer type?");
7956 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
7957 Result.setFrom(Info.Ctx, LValResult);
7966 bool InvalidBaseOK) {
7968 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
7971 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
7974 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7979 std::swap(PExp, IExp);
7981 bool EvalPtrOK = evaluatePointer(PExp, Result);
7982 if (!EvalPtrOK && !Info.noteFailure())
7996 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
8000 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8007 case CK_CPointerToObjCPointerCast:
8008 case CK_BlockPointerToObjCPointerCast:
8009 case CK_AnyPointerToBlockPointerCast:
8010 case CK_AddressSpaceConversion:
8011 if (!Visit(SubExpr))
8017 if (!Result.InvalidBase && !Result.Designator.Invalid &&
8018 !Result.IsNullPtr &&
8019 Info.Ctx.hasSameUnqualifiedType(Result.Designator.getType(Info.Ctx),
8021 Info.getStdAllocatorCaller(
"allocate")) {
8026 Result.Designator.setInvalid();
8028 CCEDiag(E, diag::note_constexpr_invalid_cast)
8031 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
8034 if (E->
getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
8035 ZeroInitialization(E);
8038 case CK_DerivedToBase:
8039 case CK_UncheckedDerivedToBase:
8042 if (!Result.Base && Result.Offset.isZero())
8048 castAs<PointerType>()->getPointeeType(),
8051 case CK_BaseToDerived:
8054 if (!Result.Base && Result.Offset.isZero())
8063 case CK_NullToPointer:
8065 return ZeroInitialization(E);
8067 case CK_IntegralToPointer: {
8068 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
8074 if (Value.
isInt()) {
8075 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
8076 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
8077 Result.Base = (
Expr*)
nullptr;
8078 Result.InvalidBase =
false;
8080 Result.Designator.setInvalid();
8081 Result.IsNullPtr =
false;
8085 Result.setFrom(Info.Ctx, Value);
8090 case CK_ArrayToPointerDecay: {
8092 if (!evaluateLValue(SubExpr, Result))
8095 APValue &Value = Info.CurrentCall->createTemporary(
8101 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
8102 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
8103 Result.addArray(Info, E, CAT);
8105 Result.addUnsizedArray(Info, E, AT->getElementType());
8109 case CK_FunctionToPointerDecay:
8110 return evaluateLValue(SubExpr, Result);
8112 case CK_LValueToRValue: {
8121 return InvalidBaseOK &&
8123 return Success(RVal, E);
8127 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8141 const bool AlignOfReturnsPreferred =
8148 return Info.Ctx.toCharUnitsFromBits(
8149 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
8152 return Info.Ctx.getTypeAlignInChars(T.
getTypePtr());
8154 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
8167 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
8168 return Info.Ctx.getDeclAlign(DRE->getDecl(),
8171 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
8172 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
8179 if (
const auto *VD = Value.Base.dyn_cast<
const ValueDecl *>())
8180 return Info.Ctx.getDeclAlign(VD);
8181 if (
const auto *E = Value.Base.dyn_cast<
const Expr *>())
8189 EvalInfo &Info,
APSInt &Alignment) {
8192 if (Alignment < 0 || !Alignment.isPowerOf2()) {
8193 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
8196 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
8197 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
8198 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
8199 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
8200 << MaxValue << ForType << Alignment;
8206 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
8207 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
8208 "Alignment should not be changed by ext/trunc");
8209 Alignment = ExtAlignment;
8210 assert(Alignment.getBitWidth() == SrcWidth);
8215 bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
8216 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
8219 if (!(InvalidBaseOK && getAllocSizeAttr(E)))
8222 Result.setInvalid(E);
8224 Result.addUnsizedArray(Info, E, PointeeTy);
8228 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
8233 return VisitBuiltinCallExpr(E, BuiltinOp);
8235 return visitNonBuiltinCallExpr(E);
8238 bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
8239 unsigned BuiltinOp) {
8240 switch (BuiltinOp) {
8241 case Builtin::BI__builtin_addressof:
8243 case Builtin::BI__builtin_assume_aligned: {
8250 LValue OffsetResult(Result);
8262 int64_t AdditionalOffset = -Offset.getZExtValue();
8267 if (OffsetResult.Base) {
8270 if (BaseAlignment < Align) {
8271 Result.Designator.setInvalid();
8274 diag::note_constexpr_baa_insufficient_alignment) << 0
8282 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
8283 Result.Designator.setInvalid();
8287 diag::note_constexpr_baa_insufficient_alignment) << 1
8289 diag::note_constexpr_baa_value_insufficient_alignment))
8290 << (int)OffsetResult.Offset.getQuantity()
8297 case Builtin::BI__builtin_align_up:
8298 case Builtin::BI__builtin_align_down: {
8318 assert(Alignment.getBitWidth() <= 64 &&
8319 "Cannot handle > 64-bit address-space");
8320 uint64_t Alignment64 = Alignment.getZExtValue();
8322 BuiltinOp == Builtin::BI__builtin_align_down
8323 ? llvm::alignDown(Result.Offset.getQuantity(), Alignment64)
8324 : llvm::alignTo(Result.Offset.getQuantity(), Alignment64));
8325 Result.adjustOffset(NewOffset - Result.Offset);
8330 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
8334 case Builtin::BI__builtin_operator_new:
8336 case Builtin::BI__builtin_launder:
8338 case Builtin::BIstrchr:
8339 case Builtin::BIwcschr:
8340 case Builtin::BImemchr:
8341 case Builtin::BIwmemchr:
8342 if (Info.getLangOpts().CPlusPlus11)
8343 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
8345 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
8347 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
8349 case Builtin::BI__builtin_strchr:
8350 case Builtin::BI__builtin_wcschr:
8351 case Builtin::BI__builtin_memchr:
8352 case Builtin::BI__builtin_char_memchr:
8353 case Builtin::BI__builtin_wmemchr: {
8354 if (!Visit(E->
getArg(0)))
8359 uint64_t MaxLength = uint64_t(-1);
8360 if (BuiltinOp != Builtin::BIstrchr &&
8361 BuiltinOp != Builtin::BIwcschr &&
8362 BuiltinOp != Builtin::BI__builtin_strchr &&
8363 BuiltinOp != Builtin::BI__builtin_wcschr) {
8367 MaxLength = N.getExtValue();
8370 if (MaxLength == 0u)
8371 return ZeroInitialization(E);
8372 if (!Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
8373 Result.Designator.Invalid)
8375 QualType CharTy = Result.Designator.getType(Info.Ctx);
8376 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
8377 BuiltinOp == Builtin::BI__builtin_memchr;
8379 Info.Ctx.hasSameUnqualifiedType(
8383 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
8388 if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) !=
CharUnits::One())
8392 uint64_t DesiredVal;
8393 bool StopAtNull =
false;
8394 switch (BuiltinOp) {
8395 case Builtin::BIstrchr:
8396 case Builtin::BI__builtin_strchr:
8403 return ZeroInitialization(E);
8406 case Builtin::BImemchr:
8407 case Builtin::BI__builtin_memchr:
8408 case Builtin::BI__builtin_char_memchr:
8412 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
8415 case Builtin::BIwcschr:
8416 case Builtin::BI__builtin_wcschr:
8419 case Builtin::BIwmemchr:
8420 case Builtin::BI__builtin_wmemchr:
8422 DesiredVal = Desired.getZExtValue();
8426 for (; MaxLength; --MaxLength) {
8431 if (Char.
getInt().getZExtValue() == DesiredVal)
8433 if (StopAtNull && !Char.
getInt())
8439 return ZeroInitialization(E);
8442 case Builtin::BImemcpy:
8443 case Builtin::BImemmove:
8444 case Builtin::BIwmemcpy:
8445 case Builtin::BIwmemmove:
8446 if (Info.getLangOpts().CPlusPlus11)
8447 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
8449 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
8451 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
8453 case Builtin::BI__builtin_memcpy:
8454 case Builtin::BI__builtin_memmove:
8455 case Builtin::BI__builtin_wmemcpy:
8456 case Builtin::BI__builtin_wmemmove: {
8457 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
8458 BuiltinOp == Builtin::BIwmemmove ||
8459 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
8460 BuiltinOp == Builtin::BI__builtin_wmemmove;
8461 bool Move = BuiltinOp == Builtin::BImemmove ||
8462 BuiltinOp == Builtin::BIwmemmove ||
8463 BuiltinOp == Builtin::BI__builtin_memmove ||
8464 BuiltinOp == Builtin::BI__builtin_wmemmove;
8467 if (!Visit(E->
getArg(0)))
8478 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
8488 if (!Src.Base || !Dest.Base) {
8490 (!Src.Base ? Src : Dest).moveInto(Val);
8491 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
8492 << Move << WChar << !!Src.Base
8496 if (Src.Designator.Invalid || Dest.Designator.Invalid)
8502 QualType T = Dest.Designator.getType(Info.Ctx);
8503 QualType SrcT = Src.Designator.getType(Info.Ctx);
8504 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
8505 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << SrcT << T;
8509 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) << Move << T;
8513 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) << Move << T;
8518 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
8522 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
8524 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
8525 << Move << WChar << 0 << T << OrigN.toString(10,
false)
8534 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
8535 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
8536 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
8537 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
8538 << Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
8539 << N.toString(10,
false);
8542 uint64_t NElems = N.getZExtValue();
8543 uint64_t NBytes = NElems * TSize;
8548 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
8549 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
8550 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
8553 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
8561 }
else if (!Move && SrcOffset >= DestOffset &&
8562 SrcOffset - DestOffset < NBytes) {
8564 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
8590 return visitNonBuiltinCallExpr(E);
8597 bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
8598 if (!Info.getLangOpts().CPlusPlus2a)
8599 Info.CCEDiag(E, diag::note_constexpr_new);
8602 if (Info.SpeculativeEvaluationDepth)
8607 bool IsNothrow =
false;
8608 bool IsPlacement =
false;
8610 Info.CurrentCall->isStdFunction() && !E->
isArray()) {
8615 if (Result.Designator.Invalid)
8619 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
8620 << isa<CXXMethodDecl>(OperatorNew) << OperatorNew;
8635 return Error(E, diag::note_constexpr_new_placement);
8648 const Expr *Stripped = *ArraySize;
8650 Stripped = ICE->getSubExpr())
8651 if (ICE->getCastKind() != CK_NoOp &&
8652 ICE->getCastKind() != CK_IntegralCast)
8663 if (ArrayBound.isSigned() && ArrayBound.isNegative()) {
8665 return ZeroInitialization(E);
8667 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
8668 << ArrayBound << (*ArraySize)->getSourceRange();
8678 return ZeroInitialization(E);
8680 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_large)
8681 << ArrayBound << (*ArraySize)->getSourceRange();
8689 auto *CAT = Info.Ctx.getAsConstantArrayType(Init->
getType());
8690 assert(CAT &&
"unexpected type for array initializer");
8693 std::max(CAT->getSize().getBitWidth(), ArrayBound.getBitWidth());
8694 llvm::APInt InitBound = CAT->getSize().zextOrSelf(Bits);
8695 llvm::APInt AllocBound = ArrayBound.zextOrSelf(Bits);
8696 if (InitBound.ugt(AllocBound)) {
8698 return ZeroInitialization(E);
8700 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
8701 << AllocBound.toString(10,
false)
8702 << InitBound.toString(10,
false)
8703 << (*ArraySize)->getSourceRange();
8709 if (InitBound != AllocBound)
8710 ResizedArrayILE = cast<InitListExpr>(Init);
8713 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound,
nullptr,
8717 "array allocation with non-array new");
8723 struct FindObjectHandler {
8730 typedef bool result_type;
8731 bool failed() {
return false; }
8735 if (!Info.Ctx.hasSameUnqualifiedType(SubobjType, AllocType)) {
8736 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type) <<
8737 SubobjType << AllocType;
8744 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
8747 bool found(APFloat &Value,
QualType SubobjType) {
8748 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
8751 } Handler = {Info, E, AllocType, AK,
nullptr};
8754 if (!Obj || !
findSubobject(Info, E, Obj, Result.Designator, Handler))
8757 Val = Handler.Value;
8766 Val = Info.createHeapAlloc(E, AllocType, Result);
8771 if (ResizedArrayILE) {
8785 Result.addArray(Info, E, cast<ConstantArrayType>(AT));
8794 class MemberPointerExprEvaluator
8795 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
8799 Result = MemberPtr(D);
8804 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
8805 : ExprEvaluatorBaseTy(Info),
Result(Result) {}
8811 bool ZeroInitialization(
const Expr *E) {
8812 return Success((
const ValueDecl*)
nullptr);
8815 bool VisitCastExpr(
const CastExpr *E);
8823 return MemberPointerExprEvaluator(Info, Result).Visit(E);
8826 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8829 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8831 case CK_NullToMemberPointer:
8833 return ZeroInitialization(E);
8835 case CK_BaseToDerivedMemberPointer: {
8843 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
8845 PathI != PathE; ++PathI) {
8846 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
8847 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
8848 if (!Result.castToDerived(Derived))
8857 case CK_DerivedToBaseMemberPointer:
8861 PathE = E->
path_end(); PathI != PathE; ++PathI) {
8862 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
8864 if (!Result.castToBase(Base))
8871 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
8874 return Success(cast<DeclRefExpr>(E->
getSubExpr())->getDecl());
8882 class RecordExprEvaluator
8883 :
public ExprEvaluatorBase<RecordExprEvaluator> {
8888 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
8889 : ExprEvaluatorBaseTy(info),
This(This),
Result(Result) {}
8895 bool ZeroInitialization(
const Expr *E) {
8896 return ZeroInitialization(E, E->
getType());
8900 bool VisitCallExpr(
const CallExpr *E) {
8901 return handleCallExpr(E, Result, &This);
8903 bool VisitCastExpr(
const CastExpr *E);
8906 return VisitCXXConstructExpr(E, E->
getType());
8925 const LValue &This,
APValue &Result) {
8926 assert(!RD->
isUnion() &&
"Expected non-union class type");
8937 End = CD->bases_end(); I !=
End; ++I, ++Index) {
8939 LValue Subobject =
This;
8943 Result.getStructBase(Index)))
8948 for (
const auto *I : RD->
fields()) {
8950 if (I->getType()->isReferenceType())
8953 LValue Subobject =
This;
8959 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
8966 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
8978 LValue Subobject =
This;
8986 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
8987 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
8994 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8997 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8999 case CK_ConstructorConversion:
9002 case CK_DerivedToBase:
9003 case CK_UncheckedDerivedToBase: {
9011 APValue *Value = &DerivedObject;
9014 PathE = E->
path_end(); PathI != PathE; ++PathI) {
9015 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
9026 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
9035 EvalInfo::EvaluatingConstructorRAII EvalObj(
9037 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
9038 CXXRD && CXXRD->getNumBases());
9054 LValue Subobject =
This;
9059 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
9060 isa<CXXDefaultInitExpr>(InitExpr));
9068 unsigned ElementNo = 0;
9069 bool Success =
true;
9072 if (CXXRD && CXXRD->getNumBases()) {
9073 for (
const auto &
Base : CXXRD->bases()) {
9074 assert(ElementNo < E->getNumInits() &&
"missing init for base class");
9077 LValue Subobject =
This;
9083 if (!Info.noteFailure())
9090 EvalObj.finishedConstructingBases();
9094 for (
const auto *Field : RD->
fields()) {
9097 if (Field->isUnnamedBitfield())
9100 LValue Subobject =
This;
9107 Subobject, Field, &Layout))
9113 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
9116 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
9117 isa<CXXDefaultInitExpr>(Init));
9122 FieldVal, Field))) {
9123 if (!Info.noteFailure())
9146 return ZeroInitialization(E, T);
9153 auto Body = FD->
getBody(Definition);
9161 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
9162 return Visit(ME->getSubExpr());
9164 if (ZeroInit && !ZeroInitialization(E, T))
9169 cast<CXXConstructorDecl>(Definition), Info,
9173 bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
9175 if (!Info.CurrentCall) {
9176 assert(Info.checkingPotentialConstantExpression());
9185 auto Body = FD->
getBody(Definition);
9191 cast<CXXConstructorDecl>(Definition), Info,
9195 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
9205 Array.addArray(Info, E, ArrayType);
9214 if (!Field->getType()->isPointerType() ||
9215 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
9226 if (Field->getType()->isPointerType() &&
9227 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
9232 ArrayType->
getSize().getZExtValue()))
9235 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
9247 bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
9252 const size_t NumFields =
9257 "The number of lambda capture initializers should equal the number of " 9258 "fields within the closure type");
9265 bool Success =
true;
9266 for (
const auto *Field : ClosureClass->
fields()) {
9269 Expr *
const CurFieldInit = *CaptureInitIt++;
9278 if (!Info.keepEvaluatingAfterFailure())
9288 APValue &Result, EvalInfo &Info) {
9290 "can't evaluate expression as a record rvalue");
9291 return RecordExprEvaluator(Info, This, Result).Visit(E);
9302 class TemporaryExprEvaluator
9303 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
9305 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
9306 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
9309 bool VisitConstructExpr(
const Expr *E) {
9311 Info.CurrentCall->createTemporary(E, E->
getType(),
false,
Result);
9315 bool VisitCastExpr(
const CastExpr *E) {
9318 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9320 case CK_ConstructorConversion:
9325 return VisitConstructExpr(E);
9328 return VisitConstructExpr(E);
9330 bool VisitCallExpr(
const CallExpr *E) {
9331 return VisitConstructExpr(E);
9334 return VisitConstructExpr(E);
9337 return VisitConstructExpr(E);
9345 return TemporaryExprEvaluator(Info, Result).Visit(E);
9353 class VectorExprEvaluator
9354 :
public ExprEvaluatorBase<VectorExprEvaluator> {
9358 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
9359 : ExprEvaluatorBaseTy(info),
Result(Result) {}
9364 Result =
APValue(V.data(), V.size());
9372 bool ZeroInitialization(
const Expr *E);
9376 bool VisitCastExpr(
const CastExpr* E);
9388 return VectorExprEvaluator(Info, Result).Visit(E);
9391 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9399 case CK_VectorSplat: {
9405 Val =
APValue(std::move(IntResult));
9407 APFloat FloatResult(0.0);
9410 Val =
APValue(std::move(FloatResult));
9417 return Success(Elts, E);
9426 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
9427 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
9430 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
9431 unsigned FloatEltSize = EltSize;
9432 if (&Sem == &APFloat::x87DoubleExtended())
9434 for (
unsigned i = 0; i < NElts; i++) {
9437 Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
9439 Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
9440 Elts.push_back(
APValue(APFloat(Sem, Elt)));
9443 for (
unsigned i = 0; i < NElts; i++) {
9446 Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
9448 Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
9454 return Success(Elts, E);
9457 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9462 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
9474 unsigned CountInits = 0, CountElts = 0;
9475 while (CountElts < NumElements) {
9477 if (CountInits < NumInits
9483 for (
unsigned j = 0; j < vlen; j++)
9488 if (CountInits < NumInits) {
9492 sInt = Info.Ctx.MakeIntValue(0, EltTy);
9493 Elements.push_back(
APValue(sInt));
9496 llvm::APFloat f(0.0);
9497 if (CountInits < NumInits) {
9501 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
9502 Elements.push_back(
APValue(f));
9507 return Success(Elements, E);
9511 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
9513 QualType EltTy = VT->getElementType();
9515 if (EltTy->isIntegerType())
9516 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
9519 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
9522 return Success(Elements, E);
9525 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9527 return ZeroInitialization(E);
9535 class ArrayExprEvaluator
9536 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
9541 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
9542 : ExprEvaluatorBaseTy(Info),
This(This),
Result(Result) {}
9545 assert(V.
isArray() &&
"expected array");
9550 bool ZeroInitialization(
const Expr *E) {
9552 Info.Ctx.getAsConstantArrayType(E->
getType());
9557 CAT->
getSize().getZExtValue());
9561 LValue Subobject =
This;
9562 Subobject.addArray(Info, E, CAT);
9567 bool VisitCallExpr(
const CallExpr *E) {
9568 return handleCallExpr(E, Result, &This);
9575 const LValue &Subobject,
9586 APValue &Result, EvalInfo &Info) {
9588 return ArrayExprEvaluator(Info, This, Result).Visit(E);
9595 "not an array rvalue");
9596 return ArrayExprEvaluator(Info, This, Result)
9597 .VisitInitListExpr(ILE, AllocType);
9604 if (isa<ImplicitValueInitExpr>(FillerExpr))
9606 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
9607 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
9616 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
9631 return VisitStringLiteral(SL, AllocType);
9634 bool Success =
true;
9637 "zero-initialized array shouldn't have any initialized elts");
9643 unsigned NumElts = CAT->
getSize().getZExtValue();
9649 NumEltsToInit = NumElts;
9651 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: " 9652 << NumEltsToInit <<
".\n");
9665 LValue Subobject =
This;
9666 Subobject.addArray(Info, E, CAT);
9667 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
9671 Info, Subobject, Init) ||
9674 if (!Info.noteFailure())
9685 assert(FillerExpr &&
"no array filler for incomplete init list");
9687 FillerExpr) && Success;
9693 !
Evaluate(Info.CurrentCall->createTemporary(
9702 uint64_t Elements = CAT->getSize().getZExtValue();
9705 LValue Subobject =
This;
9706 Subobject.addArray(Info, E, CAT);
9708 bool Success =
true;
9709 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
9713 CAT->getElementType(), 1)) {
9714 if (!Info.noteFailure())
9723 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
9724 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
9728 const LValue &Subobject,
9731 bool HadZeroInit = Value->
hasValue();
9734 unsigned N = CAT->getSize().getZExtValue();
9744 for (
unsigned I = 0; I != N; ++I)
9748 LValue ArrayElt = Subobject;
9749 ArrayElt.addArray(Info, E, CAT);
9750 for (
unsigned I = 0; I != N; ++I)
9752 CAT->getElementType()) ||
9754 CAT->getElementType(), 1))
9763 return RecordExprEvaluator(Info, Subobject, *Value)
9764 .VisitCXXConstructExpr(E, Type);
9776 class IntExprEvaluator
9777 :
public ExprEvaluatorBase<IntExprEvaluator> {
9780 IntExprEvaluator(EvalInfo &info,
APValue &result)
9781 : ExprEvaluatorBaseTy(info),
Result(result) {}
9785 "Invalid evaluation result.");
9787 "Invalid evaluation result.");
9788 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
9789 "Invalid evaluation result.");
9794 return Success(SI, E, Result);
9799 "Invalid evaluation result.");
9800 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
9801 "Invalid evaluation result.");
9803 Result.
getInt().setIsUnsigned(
9808 return Success(I, E, Result);
9811 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
9813 "Invalid evaluation result.");
9817 bool Success(uint64_t Value,
const Expr *E) {
9818 return Success(Value, E, Result);
9830 return Success(V.
getInt(), E);
9833 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
9848 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
9850 if (CheckReferencedDecl(E, E->
getDecl()))
9853 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
9857 VisitIgnoredBaseExpression(E->
getBase());
9861 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
9864 bool VisitCallExpr(
const CallExpr *E);
9865 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9870 bool VisitCastExpr(
const CastExpr* E);
9882 if (Info.ArrayInitIndex == uint64_t(-1)) {
9888 return Success(Info.ArrayInitIndex, E);
9893 return ZeroInitialization(E);
9919 class FixedPointExprEvaluator
9920 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
9924 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
9925 : ExprEvaluatorBaseTy(info),
Result(result) {}
9932 bool Success(uint64_t Value,
const Expr *E) {
9944 "Invalid evaluation result.");
9957 bool VisitCastExpr(
const CastExpr *E);
9974 return IntExprEvaluator(Info, Result).Visit(E);
9984 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
9991 bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
9993 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
9994 return Success(Evaluated, E);
10001 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
10015 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
10030 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
10034 bool SameSign = (ECD->getInitVal().isSigned()
10036 bool SameWidth = (ECD->getInitVal().getBitWidth()
10037 == Info.Ctx.getIntWidth(E->
getType()));
10038 if (SameSign && SameWidth)
10039 return Success(ECD->getInitVal(), E);
10045 Val.setIsSigned(!ECD->getInitVal().isSigned());
10047 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
10048 return Success(Val, E);
10093 switch (CanTy->getTypeClass()) {
10094 #define TYPE(ID, BASE) 10095 #define DEPENDENT_TYPE(ID, BASE) case Type::ID: 10096 #define NON_CANONICAL_TYPE(ID, BASE) case Type::ID: 10097 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID: 10098 #include "clang/AST/TypeNodes.inc" 10100 case Type::DeducedTemplateSpecialization:
10101 llvm_unreachable(
"unexpected non-canonical or dependent type");
10103 case Type::Builtin:
10105 #define BUILTIN_TYPE(ID, SINGLETON_ID) 10106 #define SIGNED_TYPE(ID, SINGLETON_ID) \ 10107 case BuiltinType::ID: return GCCTypeClass::Integer; 10108 #define FLOATING_TYPE(ID, SINGLETON_ID) \ 10109 case BuiltinType::ID: return GCCTypeClass::RealFloat; 10110 #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \ 10111 case BuiltinType::ID: break; 10112 #include "clang/AST/BuiltinTypes.def" 10113 case BuiltinType::Void:
10116 case BuiltinType::Bool:
10119 case BuiltinType::Char_U:
10120 case BuiltinType::UChar:
10121 case BuiltinType::WChar_U:
10122 case BuiltinType::Char8:
10123 case BuiltinType::Char16:
10124 case BuiltinType::Char32:
10125 case BuiltinType::UShort:
10126 case BuiltinType::UInt:
10127 case BuiltinType::ULong:
10128 case BuiltinType::ULongLong:
10129 case BuiltinType::UInt128:
10132 case BuiltinType::UShortAccum:
10133 case BuiltinType::UAccum:
10134 case BuiltinType::ULongAccum:
10135 case BuiltinType::UShortFract:
10136 case BuiltinType::UFract:
10137 case BuiltinType::ULongFract:
10138 case BuiltinType::SatUShortAccum:
10139 case BuiltinType::SatUAccum:
10140 case BuiltinType::SatULongAccum:
10141 case BuiltinType::SatUShortFract:
10142 case BuiltinType::SatUFract:
10143 case BuiltinType::SatULongFract:
10146 case BuiltinType::NullPtr:
10148 case BuiltinType::ObjCId:
10149 case BuiltinType::ObjCClass:
10150 case BuiltinType::ObjCSel:
10151 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 10152 case BuiltinType::Id: 10153 #include "clang/Basic/OpenCLImageTypes.def" 10154 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 10155 case BuiltinType::Id: 10156 #include "clang/Basic/OpenCLExtensionTypes.def" 10157 case BuiltinType::OCLSampler:
10158 case BuiltinType::OCLEvent:
10159 case BuiltinType::OCLClkEvent:
10160 case BuiltinType::OCLQueue:
10161 case BuiltinType::OCLReserveID:
10162 #define SVE_TYPE(Name, Id, SingletonId) \ 10163 case BuiltinType::Id: 10164 #include "clang/Basic/AArch64SVEACLETypes.def" 10167 case BuiltinType::Dependent:
10168 llvm_unreachable(
"unexpected dependent type");
10170 llvm_unreachable(
"unexpected placeholder type");
10175 case Type::Pointer:
10176 case Type::ConstantArray:
10177 case Type::VariableArray:
10178 case Type::IncompleteArray:
10179 case Type::FunctionNoProto:
10180 case Type::FunctionProto:
10183 case Type::MemberPointer:
10184 return CanTy->isMemberDataPointerType()
10188 case Type::Complex:
10200 case Type::BlockPointer:
10202 case Type::ExtVector:
10203 case Type::ObjCObject:
10204 case Type::ObjCInterface:
10205 case Type::ObjCObjectPointer:
10211 case Type::LValueReference:
10212 case Type::RValueReference:
10213 llvm_unreachable(
"invalid type for expression");
10216 llvm_unreachable(
"unexpected type class");
10245 if (!isa<StringLiteral>(E))
10263 SpeculativeEvaluationRAII SpeculativeEval(Info);
10268 FoldConstant Fold(Info,
true);
10291 Fold.keepDiagnostics();
10311 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
10314 if (isa<CompoundLiteralExpr>(E))
10336 if (
Cast ==
nullptr)
10343 CastKind != CK_AddressSpaceConversion)
10346 auto *SubExpr =
Cast->getSubExpr();
10347 if (!SubExpr->getType()->hasPointerRepresentation() || !SubExpr->isRValue())
10368 assert(!LVal.Designator.Invalid);
10370 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &Invalid) {
10373 if (Invalid || Parent->
isUnion())
10379 auto &
Base = LVal.getLValueBase();
10380 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
10381 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
10383 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
10385 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
10386 for (
auto *FD : IFD->chain()) {
10388 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid))
10396 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
10406 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
10407 const auto &Entry = LVal.Designator.Entries[I];
10413 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
10414 uint64_t Index = Entry.getAsArrayIndex();
10415 if (Index + 1 != CAT->getSize())
10417 BaseType = CAT->getElementType();
10420 uint64_t Index = Entry.getAsArrayIndex();
10423 BaseType = CT->getElementType();
10424 }
else if (
auto *FD = getAsField(Entry)) {
10426 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
10430 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
10442 if (LVal.Designator.Invalid)
10445 if (!LVal.Designator.Entries.empty())
10446 return LVal.Designator.isMostDerivedAnUnsizedArray();
10448 if (!LVal.InvalidBase)
10453 const auto *E = LVal.Base.dyn_cast<
const Expr *>();
10454 return !E || !isa<MemberExpr>(E);
10460 const SubobjectDesignator &
Designator = LVal.Designator;
10472 return LVal.InvalidBase &&
10473 Designator.Entries.size() == Designator.MostDerivedPathLength &&
10474 Designator.MostDerivedIsArrayElement &&
10483 if (Int.ugt(CharUnitsMax))
10496 unsigned Type,
const LValue &LVal,
10509 if (!(Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
10511 if (Type == 3 && !DetermineForCompleteObject)
10515 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10519 if (LVal.InvalidBase)
10523 return CheckedHandleSizeof(BaseTy, EndOffset);
10527 const SubobjectDesignator &
Designator = LVal.Designator;
10540 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
10552 if (!CheckedHandleSizeof(Designator.MostDerivedType, BytesPerElem))
10558 int64_t ElemsRemaining;
10559 if (Designator.MostDerivedIsArrayElement &&
10560 Designator.Entries.size() == Designator.MostDerivedPathLength) {
10561 uint64_t ArraySize = Designator.getMostDerivedArraySize();
10562 uint64_t ArrayIndex = Designator.Entries.back().getAsArrayIndex();
10563 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
10565 ElemsRemaining = Designator.isOnePastTheEnd() ? 0 : 1;
10568 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
10578 EvalInfo &Info, uint64_t &Size) {
10585 SpeculativeEvaluationRAII SpeculativeEval(Info);
10586 IgnoreSideEffectsRAII Fold(Info);
10594 LVal.setFrom(Info.Ctx, RVal);
10602 if (LVal.getLValueOffset().isNegative()) {
10613 if (EndOffset <= LVal.getLValueOffset())
10616 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
10620 bool IntExprEvaluator::VisitConstantExpr(
const ConstantExpr *E) {
10624 return ExprEvaluatorBaseTy::VisitConstantExpr(E);
10627 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10629 return VisitBuiltinCallExpr(E, BuiltinOp);
10631 return ExprEvaluatorBaseTy::VisitCallExpr(E);
10647 Info.FFDiag(E->
getArg(0));
10653 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
10654 "Bit widths must be the same");
10661 bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10662 unsigned BuiltinOp) {
10665 return ExprEvaluatorBaseTy::VisitCallExpr(E);
10667 case Builtin::BI__builtin_dynamic_object_size:
10668 case Builtin::BI__builtin_object_size: {
10672 assert(Type <= 3 &&
"unexpected type");
10676 return Success(Size, E);
10679 return Success((Type & 2) ? 0 : -1, E);
10683 switch (Info.EvalMode) {
10684 case EvalInfo::EM_ConstantExpression:
10685 case EvalInfo::EM_ConstantFold:
10686 case EvalInfo::EM_IgnoreSideEffects:
10689 case EvalInfo::EM_ConstantExpressionUnevaluated:
10691 return Success((Type & 2) ? 0 : -1, E);
10694 llvm_unreachable(
"unexpected EvalMode");
10697 case Builtin::BI__builtin_os_log_format_buffer_size: {
10703 case Builtin::BI__builtin_is_aligned: {
10711 Ptr.setFrom(Info.Ctx, Src);
10717 assert(Alignment.isPowerOf2());
10719 return Success(1, E);
10726 return Success(0, E);
10730 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
10734 assert(Src.
isInt());
10735 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
10737 case Builtin::BI__builtin_align_up: {
10745 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
10746 Src.
getInt().isUnsigned());
10747 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
10748 return Success(AlignedVal, E);
10750 case Builtin::BI__builtin_align_down: {
10759 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
10760 return Success(AlignedVal, E);
10763 case Builtin::BI__builtin_bswap16:
10764 case Builtin::BI__builtin_bswap32:
10765 case Builtin::BI__builtin_bswap64: {
10770 return Success(Val.byteSwap(), E);
10773 case Builtin::BI__builtin_classify_type:
10776 case Builtin::BI__builtin_clrsb:
10777 case Builtin::BI__builtin_clrsbl:
10778 case Builtin::BI__builtin_clrsbll: {
10783 return Success(Val.getBitWidth() - Val.getMinSignedBits(), E);
10786 case Builtin::BI__builtin_clz:
10787 case Builtin::BI__builtin_clzl:
10788 case Builtin::BI__builtin_clzll:
10789 case Builtin::BI__builtin_clzs: {
10796 return Success(Val.countLeadingZeros(), E);
10799 case Builtin::BI__builtin_constant_p: {
10802 return Success(
true, E);
10807 return Success(
false, E);
10809 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
10813 case Builtin::BI__builtin_is_constant_evaluated: {
10814 const auto *Callee = Info.CurrentCall->getCallee();
10815 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
10816 (Info.CallStackDepth == 1 ||
10821 if (Info.EvalStatus.Diag)
10822 Info.report((Info.CallStackDepth == 1) ? E->
getExprLoc()
10823 : Info.CurrentCall->CallLoc,
10824 diag::warn_is_constant_evaluated_always_true_constexpr)
10825 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated" 10826 :
"std::is_constant_evaluated");
10829 return Success(Info.InConstantContext, E);
10832 case Builtin::BI__builtin_ctz:
10833 case Builtin::BI__builtin_ctzl:
10834 case Builtin::BI__builtin_ctzll:
10835 case Builtin::BI__builtin_ctzs: {
10842 return Success(Val.countTrailingZeros(), E);
10845 case Builtin::BI__builtin_eh_return_data_regno: {
10847 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
10848 return Success(Operand, E);
10851 case Builtin::BI__builtin_expect:
10852 return Visit(E->
getArg(0));
10854 case Builtin::BI__builtin_ffs:
10855 case Builtin::BI__builtin_ffsl:
10856 case Builtin::BI__builtin_ffsll: {
10861 unsigned N = Val.countTrailingZeros();
10862 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
10865 case Builtin::BI__builtin_fpclassify: {
10870 switch (Val.getCategory()) {
10871 case APFloat::fcNaN: Arg = 0;
break;
10872 case APFloat::fcInfinity: Arg = 1;
break;
10873 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
10874 case APFloat::fcZero: Arg = 4;
break;
10876 return Visit(E->
getArg(Arg));
10879 case Builtin::BI__builtin_isinf_sign: {
10882 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
10885 case Builtin::BI__builtin_isinf: {
10888 Success(Val.isInfinity() ? 1 : 0, E);
10891 case Builtin::BI__builtin_isfinite: {
10894 Success(Val.isFinite() ? 1 : 0, E);
10897 case Builtin::BI__builtin_isnan: {
10900 Success(Val.isNaN() ? 1 : 0, E);
10903 case Builtin::BI__builtin_isnormal: {
10906 Success(Val.isNormal() ? 1 : 0, E);
10909 case Builtin::BI__builtin_parity:
10910 case Builtin::BI__builtin_parityl:
10911 case Builtin::BI__builtin_parityll: {
10916 return Success(Val.countPopulation() % 2, E);
10919 case Builtin::BI__builtin_popcount:
10920 case Builtin::BI__builtin_popcountl:
10921 case Builtin::BI__builtin_popcountll: {
10926 return Success(Val.countPopulation(), E);
10929 case Builtin::BIstrlen:
10930 case Builtin::BIwcslen:
10932 if (Info.getLangOpts().CPlusPlus11)
10933 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10935 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
10937 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10939 case Builtin::BI__builtin_strlen:
10940 case Builtin::BI__builtin_wcslen: {
10950 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
10951 String.getLValueBase().dyn_cast<
const Expr *>())) {
10954 StringRef Str = S->getBytes();
10955 int64_t Off = String.Offset.getQuantity();
10956 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
10957 S->getCharByteWidth() == 1 &&
10959 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
10960 Str = Str.substr(Off);
10962 StringRef::size_type Pos = Str.find(0);
10963 if (Pos != StringRef::npos)
10964 Str = Str.substr(0, Pos);
10966 return Success(Str.size(), E);
10973 for (uint64_t Strlen = 0; ; ++Strlen) {
10979 return Success(Strlen, E);
10985 case Builtin::BIstrcmp:
10986 case Builtin::BIwcscmp:
10987 case Builtin::BIstrncmp:
10988 case Builtin::BIwcsncmp:
10989 case Builtin::BImemcmp:
10990 case Builtin::BIbcmp:
10991 case Builtin::BIwmemcmp:
10993 if (Info.getLangOpts().CPlusPlus11)
10994 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10996 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
10998 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
11000 case Builtin::BI__builtin_strcmp:
11001 case Builtin::BI__builtin_wcscmp:
11002 case Builtin::BI__builtin_strncmp:
11003 case Builtin::BI__builtin_wcsncmp:
11004 case Builtin::BI__builtin_memcmp:
11005 case Builtin::BI__builtin_bcmp:
11006 case Builtin::BI__builtin_wmemcmp: {
11007 LValue String1, String2;
11012 uint64_t MaxLength = uint64_t(-1);
11013 if (BuiltinOp != Builtin::BIstrcmp &&
11014 BuiltinOp != Builtin::BIwcscmp &&
11015 BuiltinOp != Builtin::BI__builtin_strcmp &&
11016 BuiltinOp != Builtin::BI__builtin_wcscmp) {
11020 MaxLength = N.getExtValue();
11024 if (MaxLength == 0u)
11025 return Success(0, E);
11027 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
11028 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
11029 String1.Designator.Invalid || String2.Designator.Invalid)
11032 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
11033 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
11035 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
11036 BuiltinOp == Builtin::BIbcmp ||
11037 BuiltinOp == Builtin::BI__builtin_memcmp ||
11038 BuiltinOp == Builtin::BI__builtin_bcmp;
11040 assert(IsRawByte ||
11041 (Info.Ctx.hasSameUnqualifiedType(
11043 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
11045 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
11048 Char1.
isInt() && Char2.isInt();
11050 const auto &AdvanceElems = [&] {
11056 uint64_t BytesRemaining = MaxLength;
11059 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy1;
11063 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy2;
11066 uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)};
11067 CharUnits CharTy1Size = Info.Ctx.toCharUnitsFromBits(CharTy1Width);
11069 if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2))
11071 uint64_t BytesPerElement = CharTy1Size.
getQuantity();
11072 assert(BytesRemaining &&
"BytesRemaining should not be zero: the " 11073 "following loop considers at least one element");
11076 if (!ReadCurElems(Char1, Char2))
11083 APSInt Char1InMem = Char1.
getInt().extOrTrunc(CharTy1Width);
11084 APSInt Char2InMem = Char2.
getInt().extOrTrunc(CharTy1Width);
11085 if (Char1InMem.ne(Char2InMem)) {
11088 if (BytesPerElement == 1u) {
11090 return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E);
11096 if (!AdvanceElems())
11098 if (BytesRemaining <= BytesPerElement)
11100 BytesRemaining -= BytesPerElement;
11103 return Success(0, E);
11107 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
11108 BuiltinOp != Builtin::BIwmemcmp &&
11109 BuiltinOp != Builtin::BI__builtin_memcmp &&
11110 BuiltinOp != Builtin::BI__builtin_bcmp &&
11111 BuiltinOp != Builtin::BI__builtin_wmemcmp);
11112 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
11113 BuiltinOp == Builtin::BIwcsncmp ||
11114 BuiltinOp == Builtin::BIwmemcmp ||
11115 BuiltinOp == Builtin::BI__builtin_wcscmp ||
11116 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
11117 BuiltinOp == Builtin::BI__builtin_wmemcmp;
11119 for (; MaxLength; --MaxLength) {
11121 if (!ReadCurElems(Char1, Char2))
11125 return Success(Char1.
getInt() < Char2.
getInt() ? -1 : 1, E);
11127 return Success(Char1.
getInt().ult(Char2.
getInt()) ? -1 : 1, E);
11129 if (StopAtNull && !Char1.
getInt())
11130 return Success(0, E);
11131 assert(!(StopAtNull && !Char2.
getInt()));
11132 if (!AdvanceElems())
11136 return Success(0, E);
11139 case Builtin::BI__atomic_always_lock_free:
11140 case Builtin::BI__atomic_is_lock_free:
11141 case Builtin::BI__c11_atomic_is_lock_free: {
11159 unsigned InlineWidthBits =
11160 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
11161 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
11162 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
11168 return Success(1, E);
11171 castAs<PointerType>()->getPointeeType();
11173 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
11175 return Success(1, E);
11180 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
11181 Success(0, E) :
Error(E);
11183 case Builtin::BIomp_is_initial_device:
11185 return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E);
11186 case Builtin::BI__builtin_add_overflow:
11187 case Builtin::BI__builtin_sub_overflow:
11188 case Builtin::BI__builtin_mul_overflow:
11189 case Builtin::BI__builtin_sadd_overflow:
11190 case Builtin::BI__builtin_uadd_overflow:
11191 case Builtin::BI__builtin_uaddl_overflow:
11192 case Builtin::BI__builtin_uaddll_overflow:
11193 case Builtin::BI__builtin_usub_overflow:
11194 case Builtin::BI__builtin_usubl_overflow:
11195 case Builtin::BI__builtin_usubll_overflow:
11196 case Builtin::BI__builtin_umul_overflow:
11197 case Builtin::BI__builtin_umull_overflow:
11198 case Builtin::BI__builtin_umulll_overflow:
11199 case Builtin::BI__builtin_saddl_overflow:
11200 case Builtin::BI__builtin_saddll_overflow:
11201 case Builtin::BI__builtin_ssub_overflow:
11202 case Builtin::BI__builtin_ssubl_overflow:
11203 case Builtin::BI__builtin_ssubll_overflow:
11204 case Builtin::BI__builtin_smul_overflow:
11205 case Builtin::BI__builtin_smull_overflow:
11206 case Builtin::BI__builtin_smulll_overflow: {
11207 LValue ResultLValue;
11217 bool DidOverflow =
false;
11220 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
11221 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
11222 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
11223 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
11225 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
11227 uint64_t LHSSize = LHS.getBitWidth();
11228 uint64_t RHSSize = RHS.getBitWidth();
11229 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
11236 if (IsSigned && !AllSigned)
11239 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
11240 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
11241 Result =
APSInt(MaxBits, !IsSigned);
11245 switch (BuiltinOp) {
11247 llvm_unreachable(
"Invalid value for BuiltinOp");
11248 case Builtin::BI__builtin_add_overflow:
11249 case Builtin::BI__builtin_sadd_overflow:
11250 case Builtin::BI__builtin_saddl_overflow:
11251 case Builtin::BI__builtin_saddll_overflow:
11252 case Builtin::BI__builtin_uadd_overflow:
11253 case Builtin::BI__builtin_uaddl_overflow:
11254 case Builtin::BI__builtin_uaddll_overflow:
11255 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
11256 : LHS.uadd_ov(RHS, DidOverflow);
11258 case Builtin::BI__builtin_sub_overflow:
11259 case Builtin::BI__builtin_ssub_overflow:
11260 case Builtin::BI__builtin_ssubl_overflow:
11261 case Builtin::BI__builtin_ssubll_overflow:
11262 case Builtin::BI__builtin_usub_overflow:
11263 case Builtin::BI__builtin_usubl_overflow:
11264 case Builtin::BI__builtin_usubll_overflow:
11265 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
11266 : LHS.usub_ov(RHS, DidOverflow);
11268 case Builtin::BI__builtin_mul_overflow:
11269 case Builtin::BI__builtin_smul_overflow:
11270 case Builtin::BI__builtin_smull_overflow:
11271 case Builtin::BI__builtin_smulll_overflow:
11272 case Builtin::BI__builtin_umul_overflow:
11273 case Builtin::BI__builtin_umull_overflow:
11274 case Builtin::BI__builtin_umulll_overflow:
11275 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
11276 : LHS.umul_ov(RHS, DidOverflow);
11282 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
11283 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
11284 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
11290 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
11293 if (!APSInt::isSameValue(Temp, Result))
11294 DidOverflow =
true;
11301 return Success(DidOverflow, E);
11309 const LValue &LV) {
11312 if (!LV.getLValueBase())
11317 if (!LV.getLValueDesignator().Invalid &&
11318 !LV.getLValueDesignator().isOnePastTheEnd())
11323 QualType Ty = getType(LV.getLValueBase());
11330 return LV.getLValueOffset() == Size;
11340 class DataRecursiveIntBinOpEvaluator {
11341 struct EvalResult {
11345 EvalResult() : Failed(
false) { }
11347 void swap(EvalResult &RHS) {
11349 Failed = RHS.Failed;
11350 RHS.Failed =
false;
11356 EvalResult LHSResult;
11357 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
11360 Job(Job &&) =
default;
11362 void startSpeculativeEval(EvalInfo &Info) {
11363 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
11367 SpeculativeEvaluationRAII SpecEvalRAII;
11372 IntExprEvaluator &IntEval;
11377 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
11378 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
11393 EvalResult PrevResult;
11394 while (!Queue.empty())
11395 process(PrevResult);
11397 if (PrevResult.Failed)
return false;
11399 FinalResult.
swap(PrevResult.Val);
11404 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
11405 return IntEval.Success(Value, E, Result);
11408 return IntEval.Success(Value, E, Result);
11411 return IntEval.Error(E);
11414 return IntEval.Error(E, D);
11418 return Info.CCEDiag(E, D);
11422 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
11423 bool &SuppressRHSDiags);
11425 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
11428 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
11429 Result.Failed = !
Evaluate(Result.Val, Info, E);
11434 void process(EvalResult &Result);
11436 void enqueue(
const Expr *E) {
11438 Queue.resize(Queue.size()+1);
11439 Queue.back().E = E;
11440 Queue.back().Kind = Job::AnyExprKind;
11446 bool DataRecursiveIntBinOpEvaluator::
11447 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
11448 bool &SuppressRHSDiags) {
11451 if (LHSResult.Failed)
11452 return Info.noteSideEffect();
11461 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
11462 Success(LHSAsBool, E, LHSResult.Val);
11466 LHSResult.Failed =
true;
11470 if (!Info.noteSideEffect())
11476 SuppressRHSDiags =
true;
11485 if (LHSResult.Failed && !Info.noteFailure())
11496 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
11499 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
11501 : Offset64 + Index64);
11504 bool DataRecursiveIntBinOpEvaluator::
11505 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
11508 if (RHSResult.Failed)
11510 Result = RHSResult.Val;
11515 bool lhsResult, rhsResult;
11522 return Success(lhsResult || rhsResult, E, Result);
11524 return Success(lhsResult && rhsResult, E, Result);
11530 if (rhsResult == (E->
getOpcode() == BO_LOr))
11531 return Success(rhsResult, E, Result);
11541 if (LHSResult.Failed || RHSResult.Failed)
11544 const APValue &LHSVal = LHSResult.Val;
11545 const APValue &RHSVal = RHSResult.Val;
11569 if (!LHSExpr || !RHSExpr)
11573 if (!LHSAddrExpr || !RHSAddrExpr)
11577 RHSAddrExpr->getLabel()->getDeclContext())
11579 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
11595 return Success(Value, E, Result);
11598 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
11599 Job &job = Queue.back();
11601 switch (job.Kind) {
11602 case Job::AnyExprKind: {
11603 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
11604 if (shouldEnqueue(Bop)) {
11605 job.Kind = Job::BinOpKind;
11606 enqueue(Bop->getLHS());
11611 EvaluateExpr(job.E, Result);
11616 case Job::BinOpKind: {
11618 bool SuppressRHSDiags =
false;
11619 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
11623 if (SuppressRHSDiags)
11624 job.startSpeculativeEval(Info);
11625 job.LHSResult.swap(Result);
11626 job.Kind = Job::BinOpVisitedLHSKind;
11631 case Job::BinOpVisitedLHSKind: {
11635 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
11641 llvm_unreachable(
"Invalid Job::Kind!");
11647 class DelayedNoteFailureRAII {
11652 DelayedNoteFailureRAII(EvalInfo &Info,
bool NoteFailure =
true)
11653 : Info(Info), NoteFailure(NoteFailure) {}
11654 ~DelayedNoteFailureRAII() {
11656 bool ContinueAfterFailure = Info.noteFailure();
11657 (void)ContinueAfterFailure;
11658 assert(ContinueAfterFailure &&
11659 "Shouldn't have kept evaluating on failure.");
11673 template <
class SuccessCB,
class AfterCB>
11676 SuccessCB &&Success, AfterCB &&DoAfter) {
11680 "unsupported binary expression evaluation");
11682 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
11696 if (!LHSOK && !Info.noteFailure())
11708 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
11709 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
11712 if (!LHSOK && !Info.noteFailure())
11724 ComplexValue LHS, RHS;
11733 LHS.makeComplexFloat();
11734 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
11739 if (!LHSOK && !Info.noteFailure())
11745 RHS.makeComplexFloat();
11746 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
11750 if (LHS.isComplexFloat()) {
11751 APFloat::cmpResult CR_r =
11752 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
11753 APFloat::cmpResult CR_i =
11754 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
11755 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
11758 assert(IsEquality &&
"invalid complex comparison");
11759 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
11760 LHS.getComplexIntImag() == RHS.getComplexIntImag();
11767 APFloat RHS(0.0), LHS(0.0);
11770 if (!LHSOK && !Info.noteFailure())
11777 auto GetCmpRes = [&]() {
11778 switch (LHS.compare(RHS)) {
11779 case APFloat::cmpEqual:
11781 case APFloat::cmpLessThan:
11783 case APFloat::cmpGreaterThan:
11785 case APFloat::cmpUnordered:
11788 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
11790 return Success(GetCmpRes(), E);
11794 LValue LHSValue, RHSValue;
11797 if (!LHSOK && !Info.noteFailure())
11809 Info.FFDiag(E, diag::note_constexpr_pointer_comparison_unspecified);
11815 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
11816 (!RHSValue.Base && !RHSValue.Offset.isZero()))
11823 LHSValue.Base && RHSValue.Base)
11831 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
11833 (RHSValue.Base && RHSValue.Offset.isZero() &&
11841 return Success(CmpResult::Unequal, E);
11844 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
11845 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
11847 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
11848 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
11858 Info.CCEDiag(E, diag::note_constexpr_void_comparison);
11868 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
11869 bool WasArrayIndex;
11871 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
11878 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
11879 Mismatch < RHSDesignator.Entries.size()) {
11880 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
11881 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
11883 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
11885 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
11886 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
11889 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
11890 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
11895 diag::note_constexpr_pointer_comparison_differing_access)
11903 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
11906 assert(PtrSize <= 64 &&
"Unexpected pointer width");
11907 uint64_t Mask = ~0ULL >> (64 - PtrSize);
11908 CompareLHS &= Mask;
11909 CompareRHS &= Mask;
11914 if (!LHSValue.Base.isNull() && IsRelational) {
11915 QualType BaseTy = getType(LHSValue.Base);
11918 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
11920 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
11924 if (CompareLHS < CompareRHS)
11926 if (CompareLHS > CompareRHS)
11932 assert(IsEquality &&
"unexpected member pointer operation");
11935 MemberPtr LHSValue, RHSValue;
11938 if (!LHSOK && !Info.noteFailure())
11947 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
11948 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
11954 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
11955 if (MD->isVirtual())
11956 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
11957 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
11958 if (MD->isVirtual())
11959 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
11965 bool Equal = LHSValue == RHSValue;
11971 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
11981 bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
11988 case CmpResult::Unequal:
11989 llvm_unreachable(
"should never produce Unequal for three-way comparison");
12006 Info.Ctx.CompCategories.getInfoForType(E->
getType());
12016 return ExprEvaluatorBaseTy::VisitBinCmp(E);
12020 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12026 DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->
isAssignmentOp());
12027 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
12028 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
12032 "DataRecursiveIntBinOpEvaluator should have handled integral types");
12038 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
12039 "should only produce Unequal for equality comparisons");
12046 llvm_unreachable(
"unsupported binary operator");
12049 return Success(IsEqual == (Op == BO_EQ), E);
12051 return Success(IsLess, E);
12053 return Success(IsGreater, E);
12055 return Success(IsEqual || IsLess, E);
12057 return Success(IsEqual || IsGreater, E);
12061 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12070 LValue LHSValue, RHSValue;
12073 if (!LHSOK && !Info.noteFailure())
12083 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
12085 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
12086 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
12087 if (!LHSExpr || !RHSExpr)
12091 if (!LHSAddrExpr || !RHSAddrExpr)
12095 RHSAddrExpr->getLabel()->getDeclContext())
12097 return Success(
APValue(LHSAddrExpr, RHSAddrExpr), E);
12099 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
12100 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
12102 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
12103 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
12109 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
12112 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
12124 if (ElementSize.
isZero()) {
12125 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
12142 APSInt TrueResult = (LHS - RHS) / ElemSize;
12143 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
12145 if (Result.extend(65) != TrueResult &&
12148 return Success(Result, E);
12151 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12156 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
12180 return Success(n, E);
12182 return Success(1, E);
12195 return Success(Sizeof, E);
12200 Info.Ctx.toCharUnitsFromBits(
12206 llvm_unreachable(
"unknown expr/type trait");
12209 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
12215 for (
unsigned i = 0; i != n; ++i) {
12223 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
12227 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
12228 Result += IdxResult.getSExtValue() * ElementSize;
12241 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
12248 llvm_unreachable(
"dependent __builtin_offsetof");
12264 CurrentType = BaseSpec->
getType();
12275 return Success(Result, OOE);
12278 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12294 if (!Result.isInt())
return Error(E);
12295 const APSInt &Value = Result.getInt();
12296 if (Value.isSigned() && Value.isMinSignedValue() && E->
canOverflow() &&
12297 !
HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),
12300 return Success(-Value, E);
12305 if (!Result.isInt())
return Error(E);
12306 return Success(~Result.getInt(), E);
12312 return Success(!bres, E);
12319 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12325 case CK_BaseToDerived:
12326 case CK_DerivedToBase:
12327 case CK_UncheckedDerivedToBase:
12330 case CK_ArrayToPointerDecay:
12331 case CK_FunctionToPointerDecay:
12332 case CK_NullToPointer:
12333 case CK_NullToMemberPointer:
12334 case CK_BaseToDerivedMemberPointer:
12335 case CK_DerivedToBaseMemberPointer:
12336 case CK_ReinterpretMemberPointer:
12337 case CK_ConstructorConversion:
12338 case CK_IntegralToPointer:
12340 case CK_VectorSplat:
12341 case CK_IntegralToFloating:
12342 case CK_FloatingCast:
12343 case CK_CPointerToObjCPointerCast:
12344 case CK_BlockPointerToObjCPointerCast:
12345 case CK_AnyPointerToBlockPointerCast:
12346 case CK_ObjCObjectLValueCast:
12347 case CK_FloatingRealToComplex:
12348 case CK_FloatingComplexToReal:
12349 case CK_FloatingComplexCast:
12350 case CK_FloatingComplexToIntegralComplex:
12351 case CK_IntegralRealToComplex:
12352 case CK_IntegralComplexCast:
12353 case CK_IntegralComplexToFloatingComplex:
12354 case CK_BuiltinFnToFnPtr:
12355 case CK_ZeroToOCLOpaqueType:
12356 case CK_NonAtomicToAtomic:
12357 case CK_AddressSpaceConversion:
12358 case CK_IntToOCLSampler:
12359 case CK_FixedPointCast:
12360 case CK_IntegralToFixedPoint:
12361 llvm_unreachable(
"invalid cast kind for integral value");
12365 case CK_LValueBitCast:
12366 case CK_ARCProduceObject:
12367 case CK_ARCConsumeObject:
12368 case CK_ARCReclaimReturnedObject:
12369 case CK_ARCExtendBlockObject:
12370 case CK_CopyAndAutoreleaseBlockObject:
12373 case CK_UserDefinedConversion:
12374 case CK_LValueToRValue:
12375 case CK_AtomicToNonAtomic:
12377 case CK_LValueToRValueBitCast:
12378 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12380 case CK_MemberPointerToBoolean:
12381 case CK_PointerToBoolean:
12382 case CK_IntegralToBoolean:
12383 case CK_FloatingToBoolean:
12384 case CK_BooleanToSignedIntegral:
12385 case CK_FloatingComplexToBoolean:
12386 case CK_IntegralComplexToBoolean: {
12390 uint64_t IntResult = BoolResult;
12391 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
12392 IntResult = (uint64_t)-1;
12393 return Success(IntResult, E);
12396 case CK_FixedPointToIntegral: {
12397 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
12402 Info.Ctx.getIntWidth(DestType),
12406 return Success(Result, E);
12409 case CK_FixedPointToBoolean: {
12412 if (!
Evaluate(Val, Info, SubExpr))
12417 case CK_IntegralCast: {
12418 if (!Visit(SubExpr))
12421 if (!Result.isInt()) {
12427 if (Result.isAddrLabelDiff())
12428 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
12430 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
12434 Result.getInt()), E);
12437 case CK_PointerToIntegral: {
12438 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
12444 if (LV.getLValueBase()) {
12449 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
12452 LV.Designator.setInvalid();
12453 LV.moveInto(Result);
12461 llvm_unreachable(
"Can't cast this!");
12466 case CK_IntegralComplexToReal: {
12470 return Success(C.getComplexIntReal(), E);
12473 case CK_FloatingToIntegral: {
12481 return Success(Value, E);
12485 llvm_unreachable(
"unknown cast resulting in integral value");
12488 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
12493 if (!LV.isComplexInt())
12495 return Success(LV.getComplexIntReal(), E);
12501 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12506 if (!LV.isComplexInt())
12508 return Success(LV.getComplexIntImag(), E);
12512 return Success(0, E);
12515 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
12519 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
12523 bool IntExprEvaluator::VisitConceptSpecializationExpr(
12528 bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
12532 bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12542 if (!Result.isFixedPoint())
12545 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
12548 return Success(Negated, E);
12554 return Success(!bres, E);
12559 bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12563 "Expected destination type to be a fixed point type");
12564 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
12567 case CK_FixedPointCast: {
12575 return Success(Result, E);
12577 case CK_IntegralToFixedPoint: {
12584 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
12586 if (Overflowed && !
HandleOverflow(Info, E, IntResult, DestType))
12589 return Success(IntResult, E);
12592 case CK_LValueToRValue:
12593 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12599 bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12603 Info.Ctx.getFixedPointSemantics(E->
getType());
12614 bool AddOverflow, ConversionOverflow;
12616 .
convert(ResultFXSema, &ConversionOverflow);
12617 if ((AddOverflow || ConversionOverflow) &&
12620 return Success(Result, E);
12625 llvm_unreachable(
"Should've exited before this");
12633 class FloatExprEvaluator
12634 :
public ExprEvaluatorBase<FloatExprEvaluator> {
12637 FloatExprEvaluator(EvalInfo &info, APFloat &result)
12638 : ExprEvaluatorBaseTy(info),
Result(result) {}
12645 bool ZeroInitialization(
const Expr *E) {
12646 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
12650 bool VisitCallExpr(
const CallExpr *E);
12655 bool VisitCastExpr(
const CastExpr *E);
12666 return FloatExprEvaluator(Info, Result).Visit(E);
12673 llvm::APFloat &Result) {
12675 if (!S)
return false;
12684 else if (S->
getString().getAsInteger(0, fill))
12689 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
12691 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
12699 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
12701 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
12707 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12710 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12712 case Builtin::BI__builtin_huge_val:
12713 case Builtin::BI__builtin_huge_valf:
12714 case Builtin::BI__builtin_huge_vall:
12715 case Builtin::BI__builtin_huge_valf128:
12716 case Builtin::BI__builtin_inf:
12717 case Builtin::BI__builtin_inff:
12718 case Builtin::BI__builtin_infl:
12719 case Builtin::BI__builtin_inff128: {
12720 const llvm::fltSemantics &Sem =
12721 Info.Ctx.getFloatTypeSemantics(E->
getType());
12722 Result = llvm::APFloat::getInf(Sem);
12726 case Builtin::BI__builtin_nans:
12727 case Builtin::BI__builtin_nansf:
12728 case Builtin::BI__builtin_nansl:
12729 case Builtin::BI__builtin_nansf128:
12735 case Builtin::BI__builtin_nan:
12736 case Builtin::BI__builtin_nanf:
12737 case Builtin::BI__builtin_nanl:
12738 case Builtin::BI__builtin_nanf128:
12746 case Builtin::BI__builtin_fabs:
12747 case Builtin::BI__builtin_fabsf:
12748 case Builtin::BI__builtin_fabsl:
12749 case Builtin::BI__builtin_fabsf128:
12753 if (Result.isNegative())
12754 Result.changeSign();
12761 case Builtin::BI__builtin_copysign:
12762 case Builtin::BI__builtin_copysignf:
12763 case Builtin::BI__builtin_copysignl:
12764 case Builtin::BI__builtin_copysignf128: {
12769 Result.copySign(RHS);
12775 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
12780 Result = CV.FloatReal;
12787 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12792 Result = CV.FloatImag;
12797 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
12798 Result = llvm::APFloat::getZero(Sem);
12802 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12804 default:
return Error(E);
12810 Result.changeSign();
12815 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12817 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12821 if (!LHSOK && !Info.noteFailure())
12827 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
12832 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12837 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12839 case CK_IntegralToFloating: {
12846 case CK_FloatingCast: {
12847 if (!Visit(SubExpr))
12853 case CK_FloatingComplexToReal: {
12857 Result = V.getComplexFloatReal();
12868 class ComplexExprEvaluator
12869 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
12873 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
12874 : ExprEvaluatorBaseTy(info),
Result(Result) {}
12881 bool ZeroInitialization(
const Expr *E);
12888 bool VisitCastExpr(
const CastExpr *E);
12898 return ComplexExprEvaluator(Info, Result).Visit(E);
12901 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
12904 Result.makeComplexFloat();
12905 APFloat
Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
12906 Result.FloatReal =
Zero;
12907 Result.FloatImag =
Zero;
12909 Result.makeComplexInt();
12910 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
12911 Result.IntReal =
Zero;
12912 Result.IntImag =
Zero;
12917 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
12921 Result.makeComplexFloat();
12922 APFloat &Imag = Result.FloatImag;
12926 Result.FloatReal = APFloat(Imag.getSemantics());
12930 "Unexpected imaginary literal.");
12932 Result.makeComplexInt();
12933 APSInt &Imag = Result.IntImag;
12937 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
12942 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
12946 case CK_BaseToDerived:
12947 case CK_DerivedToBase:
12948 case CK_UncheckedDerivedToBase:
12951 case CK_ArrayToPointerDecay:
12952 case CK_FunctionToPointerDecay:
12953 case CK_NullToPointer:
12954 case CK_NullToMemberPointer:
12955 case CK_BaseToDerivedMemberPointer:
12956 case CK_DerivedToBaseMemberPointer:
12957 case CK_MemberPointerToBoolean:
12958 case CK_ReinterpretMemberPointer:
12959 case CK_ConstructorConversion:
12960 case CK_IntegralToPointer:
12961 case CK_PointerToIntegral:
12962 case CK_PointerToBoolean:
12964 case CK_VectorSplat:
12965 case CK_IntegralCast:
12966 case CK_BooleanToSignedIntegral:
12967 case CK_IntegralToBoolean:
12968 case CK_IntegralToFloating:
12969 case CK_FloatingToIntegral:
12970 case CK_FloatingToBoolean:
12971 case CK_FloatingCast:
12972 case CK_CPointerToObjCPointerCast:
12973 case CK_BlockPointerToObjCPointerCast:
12974 case CK_AnyPointerToBlockPointerCast:
12975 case CK_ObjCObjectLValueCast:
12976 case CK_FloatingComplexToReal:
12977 case CK_FloatingComplexToBoolean:
12978 case CK_IntegralComplexToReal:
12979 case CK_IntegralComplexToBoolean:
12980 case CK_ARCProduceObject:
12981 case CK_ARCConsumeObject:
12982 case CK_ARCReclaimReturnedObject:
12983 case CK_ARCExtendBlockObject:
12984 case CK_CopyAndAutoreleaseBlockObject:
12985 case CK_BuiltinFnToFnPtr:
12986 case CK_ZeroToOCLOpaqueType:
12987 case CK_NonAtomicToAtomic:
12988 case CK_AddressSpaceConversion:
12989 case CK_IntToOCLSampler:
12990 case CK_FixedPointCast:
12991 case CK_FixedPointToBoolean:
12992 case CK_FixedPointToIntegral:
12993 case CK_IntegralToFixedPoint:
12994 llvm_unreachable(
"invalid cast kind for complex value");
12996 case CK_LValueToRValue:
12997 case CK_AtomicToNonAtomic:
12999 case CK_LValueToRValueBitCast:
13000 return ExprEvaluatorBaseTy::VisitCastExpr(E);
13003 case CK_LValueBitCast:
13004 case CK_UserDefinedConversion:
13007 case CK_FloatingRealToComplex: {
13008 APFloat &Real = Result.FloatReal;
13012 Result.makeComplexFloat();
13013 Result.FloatImag = APFloat(Real.getSemantics());
13017 case CK_FloatingComplexCast: {
13029 case CK_FloatingComplexToIntegralComplex: {
13036 Result.makeComplexInt();
13038 To, Result.IntReal) &&
13040 To, Result.IntImag);
13043 case CK_IntegralRealToComplex: {
13044 APSInt &Real = Result.IntReal;
13048 Result.makeComplexInt();
13049 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
13053 case CK_IntegralComplexCast: {
13066 case CK_IntegralComplexToFloatingComplex: {
13073 Result.makeComplexFloat();
13075 To, Result.FloatReal) &&
13077 To, Result.FloatImag);
13081 llvm_unreachable(
"unknown cast resulting in complex value");
13084 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
13086 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
13090 bool LHSReal =
false, RHSReal =
false;
13095 APFloat &Real = Result.FloatReal;
13098 Result.makeComplexFloat();
13099 Result.FloatImag = APFloat(Real.getSemantics());
13102 LHSOK = Visit(E->
getLHS());
13104 if (!LHSOK && !Info.noteFailure())
13110 APFloat &Real = RHS.FloatReal;
13113 RHS.makeComplexFloat();
13114 RHS.FloatImag = APFloat(Real.getSemantics());
13118 assert(!(LHSReal && RHSReal) &&
13119 "Cannot have both operands of a complex operation be real.");
13121 default:
return Error(E);
13123 if (Result.isComplexFloat()) {
13124 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
13125 APFloat::rmNearestTiesToEven);
13127 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
13129 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
13130 APFloat::rmNearestTiesToEven);
13132 Result.getComplexIntReal() += RHS.getComplexIntReal();
13133 Result.getComplexIntImag() += RHS.getComplexIntImag();
13137 if (Result.isComplexFloat()) {
13138 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
13139 APFloat::rmNearestTiesToEven);
13141 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
13142 Result.getComplexFloatImag().changeSign();
13143 }
else if (!RHSReal) {
13144 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
13145 APFloat::rmNearestTiesToEven);
13148 Result.getComplexIntReal() -= RHS.getComplexIntReal();
13149 Result.getComplexIntImag() -= RHS.getComplexIntImag();
13153 if (Result.isComplexFloat()) {
13158 ComplexValue LHS =
Result;
13159 APFloat &A = LHS.getComplexFloatReal();
13160 APFloat &B = LHS.getComplexFloatImag();
13161 APFloat &
C = RHS.getComplexFloatReal();
13162 APFloat &D = RHS.getComplexFloatImag();
13163 APFloat &ResR = Result.getComplexFloatReal();
13164 APFloat &ResI = Result.getComplexFloatImag();
13166 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
13169 }
else if (RHSReal) {
13175 APFloat AC = A *
C;
13176 APFloat BD = B * D;
13177 APFloat AD = A * D;
13178 APFloat BC = B *
C;
13181 if (ResR.isNaN() && ResI.isNaN()) {
13182 bool Recalc =
false;
13183 if (A.isInfinity() || B.isInfinity()) {
13184 A = APFloat::copySign(
13185 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
13186 B = APFloat::copySign(
13187 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
13189 C = APFloat::copySign(APFloat(C.getSemantics()), C);
13191 D = APFloat::copySign(APFloat(D.getSemantics()), D);
13194 if (C.isInfinity() || D.isInfinity()) {
13195 C = APFloat::copySign(
13196 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
13197 D = APFloat::copySign(
13198 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
13200 A = APFloat::copySign(APFloat(A.getSemantics()), A);
13202 B = APFloat::copySign(APFloat(B.getSemantics()), B);
13205 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
13206 AD.isInfinity() || BC.isInfinity())) {
13208 A = APFloat::copySign(APFloat(A.getSemantics()), A);
13210 B = APFloat::copySign(APFloat(B.getSemantics()), B);
13212 C = APFloat::copySign(APFloat(C.getSemantics()), C);
13214 D = APFloat::copySign(APFloat(D.getSemantics()), D);
13218 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
13219 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
13224 ComplexValue LHS =
Result;
13225 Result.getComplexIntReal() =
13226 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
13227 LHS.getComplexIntImag() * RHS.getComplexIntImag());
13228 Result.getComplexIntImag() =
13229 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
13230 LHS.getComplexIntImag() * RHS.getComplexIntReal());
13234 if (Result.isComplexFloat()) {
13239 ComplexValue LHS =
Result;
13240 APFloat &A = LHS.getComplexFloatReal();
13241 APFloat &B = LHS.getComplexFloatImag();
13242 APFloat &
C = RHS.getComplexFloatReal();
13243 APFloat &D = RHS.getComplexFloatImag();
13244 APFloat &ResR = Result.getComplexFloatReal();
13245 APFloat &ResI = Result.getComplexFloatImag();
13252 B = APFloat::getZero(A.getSemantics());
13255 APFloat MaxCD = maxnum(
abs(C),
abs(D));
13256 if (MaxCD.isFinite()) {
13257 DenomLogB =
ilogb(MaxCD);
13258 C =
scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
13259 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
13261 APFloat Denom = C * C + D * D;
13262 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB,
13263 APFloat::rmNearestTiesToEven);
13264 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB,
13265 APFloat::rmNearestTiesToEven);
13266 if (ResR.isNaN() && ResI.isNaN()) {
13267 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
13268 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
13269 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
13270 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
13272 A = APFloat::copySign(
13273 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
13274 B = APFloat::copySign(
13275 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
13276 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
13277 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
13278 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
13279 C = APFloat::copySign(
13280 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
13281 D = APFloat::copySign(
13282 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
13283 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
13284 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
13289 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
13290 return Error(E, diag::note_expr_divide_by_zero);
13292 ComplexValue LHS =
Result;
13293 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
13294 RHS.getComplexIntImag() * RHS.getComplexIntImag();
13295 Result.getComplexIntReal() =
13296 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
13297 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
13298 Result.getComplexIntImag() =
13299 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
13300 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
13308 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
13322 if (Result.isComplexFloat()) {
13323 Result.getComplexFloatReal().changeSign();
13324 Result.getComplexFloatImag().changeSign();
13327 Result.getComplexIntReal() = -Result.getComplexIntReal();
13328 Result.getComplexIntImag() = -Result.getComplexIntImag();
13332 if (Result.isComplexFloat())
13333 Result.getComplexFloatImag().changeSign();
13335 Result.getComplexIntImag() = -Result.getComplexIntImag();
13340 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
13343 Result.makeComplexFloat();
13349 Result.makeComplexInt();
13357 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
13366 class AtomicExprEvaluator :
13367 public ExprEvaluatorBase<AtomicExprEvaluator> {
13368 const LValue *
This;
13371 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
13372 : ExprEvaluatorBaseTy(Info),
This(This),
Result(Result) {}
13379 bool ZeroInitialization(
const Expr *E) {
13388 bool VisitCastExpr(
const CastExpr *E) {
13391 return ExprEvaluatorBaseTy::VisitCastExpr(E);
13392 case CK_NonAtomicToAtomic:
13403 return AtomicExprEvaluator(Info, This, Result).Visit(E);
13412 class VoidExprEvaluator
13413 :
public ExprEvaluatorBase<VoidExprEvaluator> {
13415 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
13417 bool Success(
const APValue &
V,
const Expr *e) {
return true; }
13419 bool ZeroInitialization(
const Expr *E) {
return true; }
13421 bool VisitCastExpr(
const CastExpr *E) {
13424 return ExprEvaluatorBaseTy::VisitCastExpr(E);
13431 bool VisitCallExpr(
const CallExpr *E) {
13433 case Builtin::BI__assume:
13434 case Builtin::BI__builtin_assume:
13438 case Builtin::BI__builtin_operator_delete:
13445 return ExprEvaluatorBaseTy::VisitCallExpr(E);
13452 bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
13454 if (Info.SpeculativeEvaluationDepth)
13459 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
13460 << isa<CXXMethodDecl>(OperatorDelete) << OperatorDelete;
13469 if (Pointer.Designator.Invalid)
13473 if (Pointer.isNullPointer()) {
13477 if (!Info.getLangOpts().CPlusPlus2a)
13478 Info.CCEDiag(E, diag::note_constexpr_new);
13483 Info, E, Pointer, E->
isArrayForm() ? DynAlloc::ArrayNew : DynAlloc::New);
13486 QualType AllocType = Pointer.Base.getDynamicAllocType();
13490 if (!E->
isArrayForm() && Pointer.Designator.Entries.size() != 0 &&
13492 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
13501 if (VirtualDelete &&
13503 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
13504 << isa<CXXMethodDecl>(VirtualDelete) << VirtualDelete;
13510 (*Alloc)->Value, AllocType))
13518 Info.FFDiag(E, diag::note_constexpr_double_delete);
13527 return VoidExprEvaluator(Info).Visit(E);
13542 LV.moveInto(Result);
13547 if (!IntExprEvaluator(Info, Result).Visit(E))
13553 LV.moveInto(Result);
13555 llvm::APFloat F(0.0);
13563 C.moveInto(Result);
13565 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
13570 P.moveInto(Result);
13575 Info.CurrentCall->createTemporary(E, T,
false, LV);
13581 APValue &Value = Info.CurrentCall->createTemporary(E, T,
false, LV);
13586 if (!Info.getLangOpts().CPlusPlus11)
13587 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
13595 APValue &Value = Info.CurrentCall->createTemporary(E, Unqual,
false, LV);
13602 }
else if (Info.getLangOpts().CPlusPlus11) {
13603 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
13606 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
13617 const Expr *E,
bool AllowNonLiteralTypes) {
13645 if (Info.EnableNewConstInterp) {
13646 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
13660 LV.setFrom(Info.Ctx, Result);
13677 L->getType()->isUnsignedIntegerType()));
13753 bool InConstantContext)
const {
13754 assert(!isValueDependent() &&
13755 "Expression evaluator can't be called on a dependent expression.");
13756 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
13757 Info.InConstantContext = InConstantContext;
13762 bool InConstantContext)
const {
13763 assert(!isValueDependent() &&
13764 "Expression evaluator can't be called on a dependent expression.");
13772 bool InConstantContext)
const {
13773 assert(!isValueDependent() &&
13774 "Expression evaluator can't be called on a dependent expression.");
13775 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
13776 Info.InConstantContext = InConstantContext;
13782 bool InConstantContext)
const {
13783 assert(!isValueDependent() &&
13784 "Expression evaluator can't be called on a dependent expression.");
13785 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
13786 Info.InConstantContext = InConstantContext;
13792 bool InConstantContext)
const {
13793 assert(!isValueDependent() &&
13794 "Expression evaluator can't be called on a dependent expression.");
13796 if (!getType()->isRealFloatingType())
13801 !ExprResult.Val.isFloat() ||
13805 Result = ExprResult.Val.getFloat();
13810 bool InConstantContext)
const {
13811 assert(!isValueDependent() &&
13812 "Expression evaluator can't be called on a dependent expression.");
13814 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
13815 Info.InConstantContext = InConstantContext;
13818 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
13819 Result.HasSideEffects ||
13825 LV.moveInto(Result.Val);
13831 assert(!isValueDependent() &&
13832 "Expression evaluator can't be called on a dependent expression.");
13834 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
13835 EvalInfo Info(Ctx, Result, EM);
13836 Info.InConstantContext =
true;
13838 if (!::
Evaluate(Result.Val, Info,
this) || Result.HasSideEffects)
13841 if (!Info.discardCleanups())
13842 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
13845 Result.Val, Usage) &&
13852 assert(!isValueDependent() &&
13853 "Expression evaluator can't be called on a dependent expression.");
13857 if (isRValue() && (getType()->isArrayType() || getType()->
isRecordType()) &&
13862 EStatus.
Diag = &Notes;
13865 ? EvalInfo::EM_ConstantExpression
13866 : EvalInfo::EM_ConstantFold);
13867 Info.setEvaluatingDecl(VD, Value);
13868 Info.InConstantContext =
true;
13873 if (Info.EnableNewConstInterp) {
13874 auto &InterpCtx =
const_cast<ASTContext &
>(Ctx).getInterpContext();
13875 if (!InterpCtx.evaluateAsInitializer(Info, VD, Value))
13900 Info.performLifetimeExtension();
13902 if (!Info.discardCleanups())
13903 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
13911 assert(getEvaluatedValue() && !getEvaluatedValue()->isAbsent() &&
13912 "cannot evaluate destruction of non-constant-initialized variable");
13915 EStatus.
Diag = &Notes;
13918 APValue DestroyedValue = *getEvaluatedValue();
13920 EvalInfo Info(getASTContext(), EStatus, EvalInfo::EM_ConstantExpression);
13921 Info.setEvaluatingDecl(
this, DestroyedValue,
13922 EvalInfo::EvaluatingDeclKind::Dtor);
13923 Info.InConstantContext =
true;
13937 if (!Info.discardCleanups())
13938 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
13940 ensureEvaluatedStmt()->HasConstantDestruction =
true;
13947 assert(!isValueDependent() &&
13948 "Expression evaluator can't be called on a dependent expression.");
13957 assert(!isValueDependent() &&
13958 "Expression evaluator can't be called on a dependent expression.");
13961 EVResult.Diag =
Diag;
13962 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
13963 Info.InConstantContext =
true;
13967 assert(Result &&
"Could not evaluate expression");
13968 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
13970 return EVResult.Val.getInt();
13975 assert(!isValueDependent() &&
13976 "Expression evaluator can't be called on a dependent expression.");
13979 EVResult.Diag =
Diag;
13980 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
13981 Info.InConstantContext =
true;
13982 Info.CheckingForUndefinedBehavior =
true;
13986 assert(Result &&
"Could not evaluate expression");
13987 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
13989 return EVResult.Val.getInt();
13993 assert(!isValueDependent() &&
13994 "Expression evaluator can't be called on a dependent expression.");
13999 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
14000 Info.CheckingForUndefinedBehavior =
true;
14006 assert(Val.isLValue());
14034 IK_ICEIfUnevaluated,
14050 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
14055 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
14057 Info.InConstantContext =
true;
14066 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
14071 #define ABSTRACT_STMT(Node) 14072 #define STMT(Node, Base) case Expr::Node##Class: 14073 #define EXPR(Node, Base) 14074 #include "clang/AST/StmtNodes.inc" 14075 case Expr::PredefinedExprClass:
14076 case Expr::FloatingLiteralClass:
14077 case Expr::ImaginaryLiteralClass:
14078 case Expr::StringLiteralClass:
14079 case Expr::ArraySubscriptExprClass:
14080 case Expr::OMPArraySectionExprClass:
14081 case Expr::MemberExprClass:
14082 case Expr::CompoundAssignOperatorClass:
14083 case Expr::CompoundLiteralExprClass:
14084 case Expr::ExtVectorElementExprClass:
14085 case Expr::DesignatedInitExprClass:
14086 case Expr::ArrayInitLoopExprClass:
14087 case Expr::ArrayInitIndexExprClass:
14088 case Expr::NoInitExprClass:
14089 case Expr::DesignatedInitUpdateExprClass:
14090 case Expr::ImplicitValueInitExprClass:
14091 case Expr::ParenListExprClass:
14092 case Expr::VAArgExprClass:
14093 case Expr::AddrLabelExprClass:
14094 case Expr::StmtExprClass:
14095 case Expr::CXXMemberCallExprClass:
14096 case Expr::CUDAKernelCallExprClass:
14097 case Expr::CXXDynamicCastExprClass:
14098 case Expr::CXXTypeidExprClass:
14099 case Expr::CXXUuidofExprClass:
14100 case Expr::MSPropertyRefExprClass:
14101 case Expr::MSPropertySubscriptExprClass:
14102 case Expr::CXXNullPtrLiteralExprClass:
14103 case Expr::UserDefinedLiteralClass:
14104 case Expr::CXXThisExprClass:
14105 case Expr::CXXThrowExprClass:
14106 case Expr::CXXNewExprClass:
14107 case Expr::CXXDeleteExprClass:
14108 case Expr::CXXPseudoDestructorExprClass:
14109 case Expr::UnresolvedLookupExprClass:
14110 case Expr::TypoExprClass:
14111 case Expr::DependentScopeDeclRefExprClass:
14112 case Expr::CXXConstructExprClass:
14113 case Expr::CXXInheritedCtorInitExprClass:
14114 case Expr::CXXStdInitializerListExprClass:
14115 case Expr::CXXBindTemporaryExprClass:
14116 case Expr::ExprWithCleanupsClass:
14117 case Expr::CXXTemporaryObjectExprClass:
14118 case Expr::CXXUnresolvedConstructExprClass:
14119 case Expr::CXXDependentScopeMemberExprClass:
14120 case Expr::UnresolvedMemberExprClass:
14121 case Expr::ObjCStringLiteralClass:
14122 case Expr::ObjCBoxedExprClass:
14123 case Expr::ObjCArrayLiteralClass:
14124 case Expr::ObjCDictionaryLiteralClass:
14125 case Expr::ObjCEncodeExprClass:
14126 case Expr::ObjCMessageExprClass:
14127 case Expr::ObjCSelectorExprClass:
14128 case Expr::ObjCProtocolExprClass:
14129 case Expr::ObjCIvarRefExprClass:
14130 case Expr::ObjCPropertyRefExprClass:
14131 case Expr::ObjCSubscriptRefExprClass:
14132 case Expr::ObjCIsaExprClass:
14133 case Expr::ObjCAvailabilityCheckExprClass:
14134 case Expr::ShuffleVectorExprClass:
14135 case Expr::ConvertVectorExprClass:
14136 case Expr::BlockExprClass:
14138 case Expr::OpaqueValueExprClass:
14139 case Expr::PackExpansionExprClass:
14140 case Expr::SubstNonTypeTemplateParmPackExprClass:
14141 case Expr::FunctionParmPackExprClass:
14142 case Expr::AsTypeExprClass:
14143 case Expr::ObjCIndirectCopyRestoreExprClass:
14144 case Expr::MaterializeTemporaryExprClass:
14145 case Expr::PseudoObjectExprClass:
14146 case Expr::AtomicExprClass:
14147 case Expr::LambdaExprClass:
14148 case Expr::CXXFoldExprClass:
14149 case Expr::CoawaitExprClass:
14150 case Expr::DependentCoawaitExprClass:
14151 case Expr::CoyieldExprClass:
14154 case Expr::InitListExprClass: {
14160 if (cast<InitListExpr>(E)->getNumInits() == 1)
14161 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
14165 case Expr::SizeOfPackExprClass:
14166 case Expr::GNUNullExprClass:
14167 case Expr::SourceLocExprClass:
14170 case Expr::SubstNonTypeTemplateParmExprClass:
14172 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
14174 case Expr::ConstantExprClass:
14175 return CheckICE(cast<ConstantExpr>(E)->getSubExpr(), Ctx);
14177 case Expr::ParenExprClass:
14178 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
14179 case Expr::GenericSelectionExprClass:
14180 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
14181 case Expr::IntegerLiteralClass:
14182 case Expr::FixedPointLiteralClass:
14183 case Expr::CharacterLiteralClass:
14184 case Expr::ObjCBoolLiteralExprClass:
14185 case Expr::CXXBoolLiteralExprClass:
14186 case Expr::CXXScalarValueInitExprClass:
14187 case Expr::TypeTraitExprClass:
14188 case Expr::ConceptSpecializationExprClass:
14189 case Expr::RequiresExprClass:
14190 case Expr::ArrayTypeTraitExprClass:
14191 case Expr::ExpressionTraitExprClass:
14192 case Expr::CXXNoexceptExprClass:
14194 case Expr::CallExprClass:
14195 case Expr::CXXOperatorCallExprClass: {
14199 const CallExpr *CE = cast<CallExpr>(E);
14204 case Expr::CXXRewrittenBinaryOperatorClass:
14205 return CheckICE(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm(),
14207 case Expr::DeclRefExprClass: {
14208 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
14210 const ValueDecl *D = cast<DeclRefExpr>(E)->getDecl();
14216 if (isa<ParmVarDecl>(D))
14217 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
14222 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
14223 if (!Dcl->getType()->isIntegralOrEnumerationType())
14224 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
14232 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
14237 case Expr::UnaryOperatorClass: {
14260 llvm_unreachable(
"invalid unary operator class");
14262 case Expr::OffsetOfExprClass: {
14271 case Expr::UnaryExprOrTypeTraitExprClass: {
14278 case Expr::BinaryOperatorClass: {
14323 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
14326 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
14327 if (REval.isSigned() && REval.isAllOnesValue()) {
14329 if (LEval.isMinSignedValue())
14330 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
14338 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
14339 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
14345 return Worst(LHSResult, RHSResult);
14351 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
14361 return Worst(LHSResult, RHSResult);
14364 llvm_unreachable(
"invalid binary operator kind");
14366 case Expr::ImplicitCastExprClass:
14367 case Expr::CStyleCastExprClass:
14368 case Expr::CXXFunctionalCastExprClass:
14369 case Expr::CXXStaticCastExprClass:
14370 case Expr::CXXReinterpretCastExprClass:
14371 case Expr::CXXConstCastExprClass:
14372 case Expr::ObjCBridgedCastExprClass: {
14373 const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
14374 if (isa<ExplicitCastExpr>(E)) {
14379 APSInt IgnoredVal(DestWidth, !DestSigned);
14384 if (FL->getValue().convertToInteger(IgnoredVal,
14385 llvm::APFloat::rmTowardZero,
14386 &Ignored) & APFloat::opInvalidOp)
14391 switch (cast<CastExpr>(E)->getCastKind()) {
14392 case CK_LValueToRValue:
14393 case CK_AtomicToNonAtomic:
14394 case CK_NonAtomicToAtomic:
14396 case CK_IntegralToBoolean:
14397 case CK_IntegralCast:
14403 case Expr::BinaryConditionalOperatorClass: {
14406 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
14408 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
14409 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
14410 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
14412 return FalseResult;
14414 case Expr::ConditionalOperatorClass: {
14422 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
14425 if (CondResult.Kind == IK_NotICE)
14431 if (TrueResult.Kind == IK_NotICE)
14433 if (FalseResult.Kind == IK_NotICE)
14434 return FalseResult;
14435 if (CondResult.Kind == IK_ICEIfUnevaluated)
14437 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
14443 return FalseResult;
14446 case Expr::CXXDefaultArgExprClass:
14447 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
14448 case Expr::CXXDefaultInitExprClass:
14449 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
14450 case Expr::ChooseExprClass: {
14451 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
14453 case Expr::BuiltinBitCastExprClass: {
14454 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(E)))
14456 return CheckICE(cast<CastExpr>(E)->getSubExpr(), Ctx);
14460 llvm_unreachable(
"Invalid StmtClass!");
14477 if (!Result.
isInt()) {
14482 if (Value) *Value = Result.
getInt();
14488 assert(!isValueDependent() &&
14489 "Expression evaluator can't be called on a dependent expression.");
14495 if (D.Kind != IK_ICE) {
14496 if (Loc) *Loc = D.Loc;
14504 assert(!isValueDependent() &&
14505 "Expression evaluator can't be called on a dependent expression.");
14510 if (!isIntegerConstantExpr(Ctx, Loc))
14519 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
14520 Info.InConstantContext =
true;
14522 if (!::
EvaluateAsInt(
this, ExprResult, Ctx, SE_AllowSideEffects, Info))
14523 llvm_unreachable(
"ICE cannot be evaluated!");
14525 Value = ExprResult.Val.getInt();
14530 assert(!isValueDependent() &&
14531 "Expression evaluator can't be called on a dependent expression.");
14533 return CheckICE(
this, Ctx).Kind == IK_ICE;
14538 assert(!isValueDependent() &&
14539 "Expression evaluator can't be called on a dependent expression.");
14548 Status.Diag = &Diags;
14549 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
14556 Info.discardCleanups() && !Status.HasSideEffects;
14558 if (!Diags.empty()) {
14559 IsConstExpr =
false;
14560 if (Loc) *Loc = Diags[0].first;
14561 }
else if (!IsConstExpr) {
14563 if (Loc) *Loc = getExprLoc();
14566 return IsConstExpr;
14572 const Expr *This)
const {
14573 assert(!isValueDependent() &&
14574 "Expression evaluator can't be called on a dependent expression.");
14577 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
14578 Info.InConstantContext =
true;
14581 const LValue *ThisPtr =
nullptr;
14585 assert(MD &&
"Don't provide `this` for non-methods.");
14586 assert(!MD->isStatic() &&
"Don't provide `this` for static methods.");
14590 !Info.EvalStatus.HasSideEffects)
14591 ThisPtr = &ThisVal;
14595 Info.EvalStatus.HasSideEffects =
false;
14598 ArgVector ArgValues(Args.size());
14601 if ((*I)->isValueDependent() ||
14602 !
Evaluate(ArgValues[I - Args.begin()], Info, *I) ||
14603 Info.EvalStatus.HasSideEffects)
14605 ArgValues[I - Args.begin()] =
APValue();
14609 Info.EvalStatus.HasSideEffects =
false;
14614 Info.discardCleanups();
14615 Info.EvalStatus.HasSideEffects =
false;
14618 CallStackFrame Frame(Info, Callee->
getLocation(), Callee, ThisPtr,
14621 FullExpressionRAII
Scope(Info);
14622 return Evaluate(Value, Info,
this) && Scope.destroy() &&
14623 !Info.EvalStatus.HasSideEffects;
14636 Status.
Diag = &Diags;
14638 EvalInfo Info(FD->
getASTContext(), Status, EvalInfo::EM_ConstantExpression);
14639 Info.InConstantContext =
true;
14640 Info.CheckingPotentialConstantExpression =
true;
14643 if (Info.EnableNewConstInterp) {
14644 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
14645 return Diags.empty();
14655 This.set({&VIE, Info.CurrentCall->Index});
14663 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
14668 Args, FD->
getBody(), Info, Scratch,
nullptr);
14671 return Diags.empty();
14679 "Expression evaluator can't be called on a dependent expression.");
14682 Status.Diag = &Diags;
14685 EvalInfo::EM_ConstantExpressionUnevaluated);
14686 Info.InConstantContext =
true;
14687 Info.CheckingPotentialConstantExpression =
true;
14691 ArgVector ArgValues(0);
14692 bool Success =
EvaluateArgs(Args, ArgValues, Info, FD);
14695 "Failed to set up arguments for potential constant evaluation");
14696 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
14700 return Diags.empty();
14704 unsigned Type)
const {
14705 if (!getType()->isPointerType())
14709 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
const Expr * getSubExpr() const
bool hasArrayFiller() const
Return true if this is an array initializer and its array "filler" has been set.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, llvm::Type *BaseLVType, CharUnits BaseLVAlignment, llvm::Value *Addr)
static bool HandleConstructorCall(const Expr *E, const LValue &This, APValue *ArgValues, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
Defines the clang::ASTContext interface.
const BlockDecl * getBlockDecl() const
static APFixedPoint getFromIntValue(const llvm::APSInt &Value, const FixedPointSemantics &DstFXSema, bool *Overflow=nullptr)
Create an APFixedPoint with a value equal to that of the provided integer, and in the same semantics ...
The null pointer literal (C++11 [lex.nullptr])
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
Represents a function declaration or definition.
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
Expr ** getArgs()
Retrieve the call arguments.
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.
bool Cast(InterpState &S, CodePtr OpPC)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static APValue getDefaultInitValue(QualType T)
Get the value to use for a default-initialized object of type T.
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool IsGlobalLValue(APValue::LValueBase B)
PointerType - C99 6.7.5.1 - Pointer Declarators.
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
A (possibly-)qualified type.
uint64_t getValue() const
bool isMemberPointerType() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
static Opcode getOpForCompoundAssignment(Opcode Opc)
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
SourceLocation getExprLoc() const
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
bool getBoolValue() const
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
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 operator==(CanQual< T > x, CanQual< U > y)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Expr * getResultExpr()
Return the result expression of this controlling expression.
CompoundStmt * getSubStmt()
const Expr * getInit(unsigned Init) const
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Stmt - This represents one statement.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
unsigned getCallIndex() const
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.
IfStmt - This represents an if/then/else.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
An instance of this object exists for each enum constant that is defined.
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool isRealFloatingType() const
Floating point categories.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
The fixed point semantics work similarly to llvm::fltSemantics.
llvm::Expected< T > Expected
void addConst()
Add the const type qualifier to this QualType.
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isRecordType() const
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
unsigned size() const
Retrieve the number of template arguments in this template argument list.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
Decl - This represents one declaration (or definition), e.g.
__DEVICE__ long long abs(long long __n)
llvm::APFloat getValue() const
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
FunctionDecl * getOperatorNew() const
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
ConstExprUsage
Indicates how the constant expression will be used.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic, and whose semantics are that of the sole contained initializer)?
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
ParenExpr - This represents a parethesized expression, e.g.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
static ObjectUnderConstruction getTombstoneKey()
static unsigned getHashValue(const ObjectUnderConstruction &Object)
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
The base class of the type hierarchy.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsConstNonVolatile(QualType T)
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
unsigned getWidth() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a call to a C++ constructor.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
bool isZero() const
isZero - Test whether the quantity equals zero.
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
const TargetInfo & getTargetInfo() const
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...
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
llvm::DenseMap< Stmt *, Stmt * > MapTy
bool EvaluateAsFixedPoint(EvalResult &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 fixed point va...
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to...
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...
Describes the capture of a variable or of this, or of a C++1y init-capture.
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
Represents a C++ constructor within a class.
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created...
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
APFixedPoint add(const APFixedPoint &Other, bool *Overflow=nullptr) const
bool isIndeterminate() const
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin...
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
QualType getElementType() const
const Expr * getSubExpr() const
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Expr * getIndexExpr(unsigned Idx)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D)
const CXXBaseSpecifier *const * path_const_iterator
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
This file provides some common utility functions for processing Lambda related AST Constructs...
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.
bool ReturnValue(const T &V, APValue &R)
Convers a value to an APValue.
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
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 EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue.
QualType getReturnType() const
CompoundLiteralExpr - [C99 6.5.2.5].
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool HandleDestructionImpl(EvalInfo &Info, SourceLocation CallLoc, const LValue &This, APValue &Value, QualType T)
APFloat & getComplexFloatReal()
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
const T * getAs() const
Member-template getAs<specific type>'.
bool This(InterpState &S, CodePtr OpPC)
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type...
unsigned PathLength
The corresponding path length in the lvalue.
ArrayRef< LValuePathEntry > getLValuePath() const
static APValue IndeterminateValue()
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage, SourceLocation SubobjectLoc, CheckedTemporaries &CheckedTemps)
QualType getTypeInfoType() const
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
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...
bool isInvalidDecl() const
unsigned getNumPlacementArgs() const
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
CXXMethodDecl * getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find if RD declares a function that overrides this function, and if so, return it.
bool isAddrLabelDiff() const
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Expr * getExprOperand() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
static bool isAssignmentOp(Opcode Opc)
Represents a parameter to a function.
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned.
The collection of all-type qualifiers we support.
bool isVariableArrayType() const
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
bool isLValueOnePastTheEnd() const
static bool HasSameBase(const LValue &A, const LValue &B)
const ValueDecl * getMemberPointerDecl() const
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
Represents a struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
Represents a class template specialization, which refers to a class template with a given set of temp...
One of these records is kept for each identifier that is lexed.
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size)
Get the size of the given type in char units.
llvm::Optional< T > Optional
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 ...
Expr * getFalseExpr() const
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
FieldDecl * getField() const
For a field offsetof node, returns the field.
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(), or __builtin_FILE().
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
Used for GCC's __alignof.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
field_range fields() const
SourceLocation getBeginLoc() const LLVM_READONLY
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 ...
Represents a member of a struct/union/class.
CheckEvaluationResultKind
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
bool Zero(InterpState &S, CodePtr OpPC)
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
static bool hasVirtualDestructor(QualType T)
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
bool isReferenceType() const
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction...
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Stmt *const * const_body_iterator
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
unsigned getArraySize() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
__DEVICE__ int max(int __a, int __b)
Symbolic representation of typeid(T) for some type T.
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
unsigned getCharByteWidth() const
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
specific_decl_iterator< FieldDecl > field_iterator
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
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...
static bool isRelationalOp(Opcode Opc)
static bool IsWeakLValue(const LValue &Value)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
bool isReplaceableGlobalAllocationFunction(bool *IsAligned=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
Describes an C or C++ initializer list.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. ...
Optional< Expr * > getArraySize()
bool isBitField() const
Determines whether this field is a bitfield.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
ForStmt - This represents a 'for (init;cond;inc)' stmt.
unsigned getLength() const
static bool isEqualityOp(Opcode Opc)
static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, llvm::APInt &Res)
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
FunctionDecl * getOperatorDelete() const
bool isElidable() const
Whether this construction is elidable.
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)...
CharUnits - This is an opaque type for sizes expressed in character units.
APValue Val
Val - This is the value the expression can be folded to.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
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...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
ArrayRef< NamedDecl * > chain() const
Expr * getInitializer()
The initializer of this new-expression.
path_iterator path_begin()
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 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 isRecordType(QualType T)
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...
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage=Expr::EvaluateForCodeGen)
Check that this core constant expression value is a valid value for a constant expression.
bool isComplexFloat() const
bool isFixedPoint() const
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
bool isComplexInt() const
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
ObjCStringLiteral, used for Objective-C string literals i.e.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
Scope - A scope is a transient data structure that is used while parsing the program.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
field_iterator field_begin() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
CaseStmt - Represent a case statement.
static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
base_class_iterator bases_begin()
Helper class for OffsetOfExpr.
Represents binding an expression to a temporary.
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 void expandArray(APValue &Array, unsigned Index)
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
APSInt & getComplexIntReal()
A binding in a decomposition declaration.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
A default argument (C++ [dcl.fct.default]).
static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point...
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Represents the this expression in C++.
bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
const CXXRecordDecl * Type
The dynamic class type of the object.
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...
const Expr * getExpr() const
Get the initialization expression that will be used.
APValue & getVectorElt(unsigned I)
The APFixedPoint class works similarly to APInt/APSInt in that it is a functional replacement for a s...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
static bool EvaluateArgs(ArrayRef< const Expr *> Args, ArgVector &ArgValues, EvalInfo &Info, const FunctionDecl *Callee)
EvaluateArgs - Evaluate the arguments to a function call.
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
ConditionalOperator - The ?: ternary operator.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
StringRef getString() const
static GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static bool handleCompoundAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
CompoundStmt - This represents a group of statements like { stmt stmt }.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
unsigned getVersion() const
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool hasLValuePath() const
QualType getComputationLHSType() const
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...
CastKind
CastKind - The kind of operation required for a conversion.
APValue & getArrayFiller()
Specifies that the expression should never be value-dependent.
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 ...
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, APValue *&Result, const LValue *LVal)
Try to evaluate the initializer for a variable declaration.
BaseOrMemberType getAsBaseOrMember() const
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
bool HasUndefinedBehavior
Whether the evaluation hit undefined behavior.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getValue() const
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 hasArrayFiller() const
capture_const_iterator captures_end() const
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
static unsigned getMaxIndex()
QualType getElementType() const
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr...
static bool isRead(AccessKinds AK)
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Allow any unmodeled side effect.
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.
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
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 ...
bool isDefaulted() const
Whether this function is defaulted per C++0x.
A non-discriminated union of a base, field, or array index.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
static bool HandleConversionToBool(const APValue &Val, bool &Result)
void EvaluateForOverflow(const ASTContext &Ctx) const
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Implements a partial diagnostic which may not be emitted.
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to...
unsigned getPackLength() const
Retrieve the length of the parameter pack.
const T * castAs() const
Member-template castAs<specific type>.
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, Expr::ConstExprUsage Usage, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Represents a C++ destructor within a class.
unsigned getNumInits() const
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
Expr * getSubExpr() const
Get the initializer to use for each array element.
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
bool isNullPtrType() const
field_iterator field_end() const
QualType getArgumentType() const
DeclContext * getDeclContext()
uint32_t getCodeUnit(size_t i) const
bool isAnyComplexType() const
A partial diagnostic which we might know in advance that we are not going to emit.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
TypeSourceInfo * getTypeSourceInfo() const
Represents an expression that computes the length of a parameter pack.
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
void removeLocalVolatile()
Defines the clang::TypeLoc interface and its subclasses.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
Kind getKind() const
Determine what kind of offsetof node this is.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
APValue & getStructField(unsigned i)
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...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
bool isSatisfied() const
Whether or not the requires clause is satisfied.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
static bool IsStringLiteralCall(const CallExpr *E)
Should this call expression be treated as a string literal?
QualType getRecordType(const RecordDecl *Decl) const
SwitchCase * getSwitchCaseList()
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Represents a GCC generic vector type.
bool isNullPointer() const
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
QualType getTypeOperand(ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
const OffsetOfNode & getComponent(unsigned Idx) const
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
APSInt & getComplexIntImag()
The result type of a method or function.
Symbolic representation of a dynamic allocation.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const Expr * getSubExpr() const
const Expr * getSubExpr() const
llvm::iterator_range< semantics_iterator > semantics()
bool isNull() const
Return true if this QualType doesn't point to a type yet.
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, and check for overflow in the original type (if that type was not an unsigned type).
const FieldDecl * getUnionField() const
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
DoStmt - This represents a 'do/while' stmt.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
APValue getAPValueResult() const
bool isVoidPointerType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
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.
RecordDecl * getDecl() const
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
Base class for stack frames, shared between VM and walker.
APValue & getStructBase(unsigned i)
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
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...
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
static ICEDiag Worst(ICEDiag A, ICEDiag B)
APValue & getArrayInitializedElt(unsigned I)
This object has an indeterminate value (C++ [basic.indet]).
A field in a dependent type, known only by its name.
QualType getCanonicalType() const
Represents a call to an inherited base class constructor from an inheriting constructor.
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
unsigned path_size() const
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static Optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
const LValueBase getLValueBase() const
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
bool isGlobalLValue() const
bool isExpressibleAsConstantInitializer() const
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant...
Encodes a location in the source.
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isPure() const
Whether this virtual function is pure, i.e.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
LangAS getAddressSpace() const
Return the address space of this type.
Expr * getSubExpr() const
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
CastKind getCastKind() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
APValue & getUnionValue()
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Represents a C++2a __builtin_bit_cast(T, v) expression.
ASTContext & getASTContext() const LLVM_READONLY
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
QualType getElementType() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
static bool IsLiteralLValue(const LValue &Value)
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
Represents a static or instance method of a struct/union/class.
static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *This, ArrayRef< const Expr *> Args, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
QualType getAllocatedType() const
const ParmVarDecl * getParamDecl(unsigned i) const
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...
bool isMemberPointer() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
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 EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
UnaryExprOrTypeTrait getKind() const
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
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...
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
TypeClass getTypeClass() const
Used for C's _Alignof and C++'s alignof.
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool isLogicalOp(Opcode Opc)
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
An expression trait intrinsic.
EnumDecl * getDecl() const
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
bool isVectorType() const
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 _...
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Represents the current source location and context used to determine the value of the source location...
ObjCBoxedExpr - used for generalized expression boxing.
bool isArgumentType() const
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration...
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
bool isMemberPointerToDerivedMember() const
Defines the fixed point number interface.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const Expr * getInitializer() const
CompoundAssignOperator - For compound assignments (e.g.
CXXConstructorDecl * getConstructor() const
Represents a C11 generic selection.
const Expr * getBase() const
EvalStatus is a struct with detailed info about an evaluation in progress.
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
Represents an element in a path from a derived class to a base class.
AddrLabelExpr - The GNU address of label extension, representing &&label.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
bool isStringType() const
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condnition evaluates to false;...
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
QualType getDynamicAllocType() const
bool isTypeOperand() const
Dataflow Directional Tag Classes.
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
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...
bool isValid() const
Return true if this is a valid SourceLocation object.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
[C99 6.4.2.2] - A predefined identifier such as func.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
EvalResult is a struct with detailed info about an evaluated expression.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
static bool isZeroSized(const LValue &Value)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
bool NE(InterpState &S, CodePtr OpPC)
Represents a field injected from an anonymous union/struct into the parent scope. ...
AccessSpecifier getAccess() const
const Expr * getInit() const
A decomposition declaration.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
StmtClass getStmtClass() const
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 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 getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined...
const Expr * getExpr() const
bool isBooleanType() const
unsigned getArrayInitializedElts() const
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
A pointer to member type per C++ 8.3.3 - Pointers to members.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
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...
bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const
Try to convert this value to an integral constant.
ExplicitCastExpr - An explicit cast written in the source code.
Expr * getPlacementArg(unsigned I)
body_iterator body_begin()
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
static bool isAnyAccess(AccessKinds AK)
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
llvm::APInt getValue() const
LabelDecl * getLabel() const
static bool HandleUnionActiveMemberChange(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 EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
SwitchStmt - This represents a 'switch' stmt.
bool isStringLiteralInit() const
unsigned getIntWidth(QualType T) const
bool isIncompleteArrayType() const
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 bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
bool HasSideEffects
Whether the evaluated expression has side effects.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'perator new' or to `__builtin_operator_new'.
Complex values, per C99 6.2.5p11.
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6.7.5p3.
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
bool checkInitIsICE() const
Determine whether the value of the initializer attached to this declaration is an integral constant e...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage, const ASTContext &Ctx) const
Evaluate an expression that is required to be a constant expression.
static bool hasFields(const CXXRecordDecl *RD)
Determine if a class has any fields that might need to be copied by a trivial copy or move operation...
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
ObjCEncodeExpr, used for @encode in Objective-C.
An implicit indirection through a C++ base class, when the field found is in a base class...
const llvm::APInt & getSize() const
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.
bool isAtomicType() const
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
bool isFunctionType() const
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
Expr * getReplacement() const
static bool isAdditiveOp(Opcode Opc)
Expr * getArg(unsigned Arg)
Return the specified argument.
Base for LValueReferenceType and RValueReferenceType.
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
The template argument is a type.
APFixedPoint convert(const FixedPointSemantics &DstSema, bool *Overflow=nullptr) const
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
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 HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Represents a base class of a C++ class.
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...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
DeclStmt * getRangeStmt()
static bool isIncrementOp(Opcode Op)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
A use of a default initializer in a constructor or in aggregate initialization.
A template argument list.
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...
const SwitchCase * getNextSwitchCase() const
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
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...
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
ValueKind getKind() const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ActionResult< Expr * > ExprResult
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasUnaligned() const
APFloat & getComplexFloatImag()
Represents a C++ struct/union/class.
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage...
Interface for the VM to interact with the AST walker's context.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
Expr * getTrueExpr() const
Represents a loop initializing the elements of an array.
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
static bool isReadByLvalueToRvalueConversion(QualType T)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
There is no such object (it's outside its lifetime).
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, SourceLocation *Loc)
Evaluate an expression as a C++11 integral constant expression.
WhileStmt - This represents a 'while' stmt.
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
Represents the specialization of a concept - evaluates to a prvalue of type bool. ...
base_class_iterator bases_end()
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...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
This class is used for builtin types like 'int'.
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
__DEVICE__ int min(int __a, int __b)
bool isGlobalDelete() const
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
bool isComplexIntegerType() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
AccessSpecifier Access
The access along this inheritance path.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
static Decl::Kind getKind(const Decl *D)
unsigned getNumElements() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
unsigned getNumComponents() const
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
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...
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression...
A rewritten comparison expression that was originally written using operator syntax.
A reference to a declared variable, function, enum, etc.
Designator - A designator in a C99 designated initializer.
SourceLocation getBeginLoc() const
bool isPointerType() const
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 bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
capture_const_iterator captures_begin() const
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluted - Return true if this expression might be usable in a constant expr...
DeclStmt * getLoopVarStmt()
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
bool isFloatingType() const
static bool isModification(AccessKinds AK)
static CharUnits GetAlignOfType(EvalInfo &Info, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
This represents a decl that may have a name.
A boolean literal, per ([C++ lex.bool] Boolean literals).
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type, member-designator).
APValue::ValueKind getResultAPValueKind() const
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Automatic storage duration (most local variables).
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr...
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
DeclStmt * getBeginStmt()
bool isFunctionPointerType() const
bool isInStdNamespace() const
static bool isComparisonOp(Opcode Opc)
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
Attempt to be ABI-compatible with code generated by Clang 7.0.x (SVN r338536).
const LangOptions & getLangOpts() const
Represents the canonical version of C arrays with a specified constant size.
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.
Defines enum values for all the target-independent builtin functions.
Declaration of a template function.
Represents an implicitly-generated value initialization of an object of a given type.
APFixedPoint & getFixedPoint()
bool Sub(InterpState &S, CodePtr OpPC)
Attr - This represents one attribute.
SourceLocation getLocation() 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.
QualType getType() const
Return the type wrapped by this type source info.
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...
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the the correct result kind for this category.
CharUnits & getLValueOffset()
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
static ObjectUnderConstruction getEmptyKey()
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...
QualType getType() const
Retrieves the type of the base class.
unsigned getVectorLength() const