50 #include "llvm/ADT/Optional.h" 51 #include "llvm/ADT/SmallBitVector.h" 52 #include "llvm/Support/SaveAndRestore.h" 53 #include "llvm/Support/raw_ostream.h" 57 #define DEBUG_TYPE "exprconstant" 59 using namespace clang;
69 struct CallStackFrame;
72 using SourceLocExprScopeGuard =
85 for (
auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
86 Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
102 dyn_cast<MaterializeTemporaryExpr>(Base)) {
105 const Expr *Temp = MTE->GetTemporaryExpr();
110 if (!Adjustments.empty())
134 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
136 return Callee ? Callee->
getAttr<AllocSizeAttr>() :
nullptr;
143 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
151 if (
const auto *FE = dyn_cast<FullExpr>(E))
154 if (
const auto *Cast = dyn_cast<CastExpr>(E))
157 if (
const auto *CE = dyn_cast<CallExpr>(E))
158 return getAllocSizeAttr(CE) ? CE :
nullptr;
172 static const uint64_t AssumedSizeForUnsizedArray =
183 bool &FirstEntryIsUnsizedArray) {
186 assert(!isBaseAnAllocSizeCall(Base) &&
187 "Unsized arrays shouldn't appear here");
188 unsigned MostDerivedLength = 0;
189 Type = getType(Base);
191 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
195 MostDerivedLength = I + 1;
198 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
199 ArraySize = CAT->getSize().getZExtValue();
201 assert(I == 0 &&
"unexpected unsized array designator");
202 FirstEntryIsUnsizedArray =
true;
203 ArraySize = AssumedSizeForUnsizedArray;
209 MostDerivedLength = I + 1;
211 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
212 Type = FD->getType();
214 MostDerivedLength = I + 1;
222 return MostDerivedLength;
227 CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex,
232 struct SubobjectDesignator {
236 unsigned Invalid : 1;
239 unsigned IsOnePastTheEnd : 1;
242 unsigned FirstEntryIsAnUnsizedArray : 1;
245 unsigned MostDerivedIsArrayElement : 1;
249 unsigned MostDerivedPathLength : 28;
258 uint64_t MostDerivedArraySize;
268 SubobjectDesignator() : Invalid(
true) {}
270 explicit SubobjectDesignator(
QualType T)
271 : Invalid(
false), IsOnePastTheEnd(
false),
272 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
273 MostDerivedPathLength(0), MostDerivedArraySize(0),
274 MostDerivedType(T) {}
278 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
279 MostDerivedPathLength(0), MostDerivedArraySize(0) {
280 assert(V.
isLValue() &&
"Non-LValue used to make an LValue designator?");
284 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
286 bool IsArray =
false;
287 bool FirstIsUnsizedArray =
false;
288 MostDerivedPathLength = findMostDerivedSubobject(
290 MostDerivedType, IsArray, FirstIsUnsizedArray);
291 MostDerivedIsArrayElement = IsArray;
292 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
298 unsigned NewLength) {
302 assert(Base &&
"cannot truncate path for null pointer");
303 assert(NewLength <= Entries.size() &&
"not a truncation");
305 if (NewLength == Entries.size())
307 Entries.resize(NewLength);
309 bool IsArray =
false;
310 bool FirstIsUnsizedArray =
false;
311 MostDerivedPathLength = findMostDerivedSubobject(
312 Ctx, Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
313 FirstIsUnsizedArray);
314 MostDerivedIsArrayElement = IsArray;
315 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
325 bool isMostDerivedAnUnsizedArray()
const {
326 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
327 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
332 uint64_t getMostDerivedArraySize()
const {
333 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
334 return MostDerivedArraySize;
338 bool isOnePastTheEnd()
const {
342 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
343 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
344 MostDerivedArraySize)
352 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
353 if (Invalid || isMostDerivedAnUnsizedArray())
359 bool IsArray = MostDerivedPathLength == Entries.size() &&
360 MostDerivedIsArrayElement;
361 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
362 : (uint64_t)IsOnePastTheEnd;
364 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
365 return {ArrayIndex, ArraySize - ArrayIndex};
369 bool isValidSubobject()
const {
372 return !isOnePastTheEnd();
380 assert(!Invalid &&
"invalid designator has no subobject type");
381 return MostDerivedPathLength == Entries.size()
388 Entries.push_back(PathEntry::ArrayIndex(0));
392 MostDerivedIsArrayElement =
true;
393 MostDerivedArraySize = CAT->
getSize().getZExtValue();
394 MostDerivedPathLength = Entries.size();
398 void addUnsizedArrayUnchecked(
QualType ElemTy) {
399 Entries.push_back(PathEntry::ArrayIndex(0));
401 MostDerivedType = ElemTy;
402 MostDerivedIsArrayElement =
true;
406 MostDerivedArraySize = AssumedSizeForUnsizedArray;
407 MostDerivedPathLength = Entries.size();
411 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
415 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
416 MostDerivedType = FD->getType();
417 MostDerivedIsArrayElement =
false;
418 MostDerivedArraySize = 0;
419 MostDerivedPathLength = Entries.size();
423 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
424 Entries.push_back(PathEntry::ArrayIndex(Imag));
428 MostDerivedType = EltTy;
429 MostDerivedIsArrayElement =
true;
430 MostDerivedArraySize = 2;
431 MostDerivedPathLength = Entries.size();
433 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
434 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
437 void adjustIndex(EvalInfo &Info,
const Expr *E, APSInt N) {
438 if (Invalid || !N)
return;
439 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
440 if (isMostDerivedAnUnsizedArray()) {
441 diagnoseUnsizedArrayPointerArithmetic(Info, E);
445 Entries.back() = PathEntry::ArrayIndex(
446 Entries.back().getAsArrayIndex() + TruncatedN);
453 bool IsArray = MostDerivedPathLength == Entries.size() &&
454 MostDerivedIsArrayElement;
455 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
456 : (uint64_t)IsOnePastTheEnd;
458 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
460 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
463 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
464 (llvm::APInt&)N += ArrayIndex;
465 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
466 diagnosePointerArithmetic(Info, E, N);
471 ArrayIndex += TruncatedN;
472 assert(ArrayIndex <= ArraySize &&
473 "bounds check succeeded for out-of-bounds index");
476 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
478 IsOnePastTheEnd = (ArrayIndex != 0);
483 struct CallStackFrame {
487 CallStackFrame *Caller;
505 typedef std::pair<const void *, unsigned> MapKeyTy;
506 typedef std::map<MapKeyTy, APValue>
MapTy;
518 unsigned CurTempVersion = TempVersionStack.back();
520 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
522 void pushTempVersion() {
523 TempVersionStack.push_back(++CurTempVersion);
526 void popTempVersion() {
527 TempVersionStack.pop_back();
538 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
547 APValue *getTemporary(
const void *Key,
unsigned Version) {
548 MapKeyTy KV(Key, Version);
549 auto LB = Temporaries.lower_bound(KV);
550 if (LB != Temporaries.end() && LB->first == KV)
554 assert((LB == Temporaries.end() || LB->first.first != Key) &&
555 (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) &&
556 "Element with key 'Key' found in map");
561 APValue *getCurrentTemporary(
const void *Key) {
562 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
563 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
564 return &std::prev(UB)->second;
569 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
570 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
571 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
572 return std::prev(UB)->first.second;
580 class ThisOverrideRAII {
582 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
583 : Frame(Frame), OldThis(Frame.This) {
585 Frame.This = NewThis;
587 ~ThisOverrideRAII() {
588 Frame.This = OldThis;
591 CallStackFrame &Frame;
592 const LValue *OldThis;
597 class OptionalDiagnostic {
611 OptionalDiagnostic &
operator<<(
const APSInt &I) {
615 *Diag << StringRef(Buffer.data(), Buffer.size());
620 OptionalDiagnostic &
operator<<(
const APFloat &F) {
629 llvm::APFloat::semanticsPrecision(F.getSemantics());
630 precision = (precision * 59 + 195) / 196;
632 F.toString(Buffer, precision);
633 *Diag << StringRef(Buffer.data(), Buffer.size());
642 *Diag << StringRef(Buffer.data(), Buffer.size());
650 llvm::PointerIntPair<APValue*, 1, bool>
Value;
653 Cleanup(
APValue *Val,
bool IsLifetimeExtended)
654 :
Value(Val, IsLifetimeExtended) {}
656 bool isLifetimeExtended()
const {
return Value.getInt(); }
658 *Value.getPointer() =
APValue();
663 struct ObjectUnderConstruction {
666 friend bool operator==(
const ObjectUnderConstruction &LHS,
667 const ObjectUnderConstruction &RHS) {
668 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
670 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
681 return {Base::getEmptyKey(), {}}; }
683 return {Base::getTombstoneKey(), {}};
688 static bool isEqual(
const ObjectUnderConstruction &LHS,
689 const ObjectUnderConstruction &RHS) {
717 CallStackFrame *CurrentCall;
720 unsigned CallStackDepth;
723 unsigned NextCallIndex;
732 CallStackFrame BottomFrame;
747 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
748 ObjectsUnderConstruction;
750 struct EvaluatingConstructorRAII {
752 ObjectUnderConstruction Object;
754 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
756 : EI(EI), Object(Object) {
758 EI.ObjectsUnderConstruction
759 .insert({Object, HasBases ? ConstructionPhase::Bases
760 : ConstructionPhase::AfterBases})
763 void finishedConstructingBases() {
764 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
766 ~EvaluatingConstructorRAII() {
767 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
774 return ObjectsUnderConstruction.lookup({Base, Path});
779 unsigned SpeculativeEvaluationDepth = 0;
783 uint64_t ArrayInitIndex = -1;
787 bool HasActiveDiagnostic;
791 bool HasFoldFailureDiagnostic;
795 bool InConstantContext;
797 enum EvaluationMode {
800 EM_ConstantExpression,
806 EM_PotentialConstantExpression,
815 EM_EvaluateForOverflow,
819 EM_IgnoreSideEffects,
826 EM_ConstantExpressionUnevaluated,
835 EM_PotentialConstantExpressionUnevaluated,
840 bool checkingPotentialConstantExpression()
const {
841 return EvalMode == EM_PotentialConstantExpression ||
842 EvalMode == EM_PotentialConstantExpressionUnevaluated;
848 bool checkingForOverflow() {
return EvalMode == EM_EvaluateForOverflow; }
851 : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(
nullptr),
852 CallStackDepth(0), NextCallIndex(1),
853 StepsLeft(getLangOpts().ConstexprStepLimit),
855 EvaluatingDecl((
const ValueDecl *)
nullptr),
856 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
857 HasFoldFailureDiagnostic(
false),
858 InConstantContext(
false), EvalMode(Mode) {}
861 EvaluatingDecl = Base;
862 EvaluatingDeclValue = &
Value;
870 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
872 if (NextCallIndex == 0) {
874 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
877 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
879 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
880 << getLangOpts().ConstexprCallDepth;
884 std::pair<CallStackFrame *, unsigned>
885 getCallFrameAndDepth(
unsigned CallIndex) {
886 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
889 unsigned Depth = CallStackDepth;
890 CallStackFrame *Frame = CurrentCall;
891 while (Frame->Index > CallIndex) {
892 Frame = Frame->Caller;
895 if (Frame->Index == CallIndex)
896 return {Frame, Depth};
900 bool nextStep(
const Stmt *S) {
902 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
913 EvalStatus.
Diag->push_back(std::make_pair(Loc, PD));
914 return EvalStatus.
Diag->back().second;
918 void addCallStack(
unsigned Limit);
922 unsigned ExtraNotes,
bool IsCCEDiag) {
924 if (EvalStatus.
Diag) {
931 if (!EvalStatus.
Diag->empty()) {
933 case EM_ConstantFold:
934 case EM_IgnoreSideEffects:
935 case EM_EvaluateForOverflow:
936 if (!HasFoldFailureDiagnostic)
940 case EM_ConstantExpression:
941 case EM_PotentialConstantExpression:
942 case EM_ConstantExpressionUnevaluated:
943 case EM_PotentialConstantExpressionUnevaluated:
944 HasActiveDiagnostic =
false;
945 return OptionalDiagnostic();
949 unsigned CallStackNotes = CallStackDepth - 1;
952 CallStackNotes =
std::min(CallStackNotes, Limit + 1);
953 if (checkingPotentialConstantExpression())
956 HasActiveDiagnostic =
true;
957 HasFoldFailureDiagnostic = !IsCCEDiag;
958 EvalStatus.
Diag->clear();
959 EvalStatus.
Diag->reserve(1 + ExtraNotes + CallStackNotes);
960 addDiag(Loc, DiagId);
961 if (!checkingPotentialConstantExpression())
963 return OptionalDiagnostic(&(*EvalStatus.
Diag)[0].second);
965 HasActiveDiagnostic =
false;
966 return OptionalDiagnostic();
972 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
973 unsigned ExtraNotes = 0) {
974 return Diag(Loc, DiagId, ExtraNotes,
false);
978 = diag::note_invalid_subexpr_in_const_expr,
979 unsigned ExtraNotes = 0) {
982 HasActiveDiagnostic =
false;
983 return OptionalDiagnostic();
992 = diag::note_invalid_subexpr_in_const_expr,
993 unsigned ExtraNotes = 0) {
996 if (!EvalStatus.
Diag || !EvalStatus.
Diag->empty()) {
997 HasActiveDiagnostic =
false;
998 return OptionalDiagnostic();
1000 return Diag(Loc, DiagId, ExtraNotes,
true);
1003 = diag::note_invalid_subexpr_in_const_expr,
1004 unsigned ExtraNotes = 0) {
1005 return CCEDiag(E->
getExprLoc(), DiagId, ExtraNotes);
1009 if (!HasActiveDiagnostic)
1010 return OptionalDiagnostic();
1011 return OptionalDiagnostic(&addDiag(Loc, DiagId));
1016 if (HasActiveDiagnostic) {
1017 EvalStatus.
Diag->insert(EvalStatus.
Diag->end(),
1018 Diags.begin(), Diags.end());
1024 bool keepEvaluatingAfterSideEffect() {
1026 case EM_PotentialConstantExpression:
1027 case EM_PotentialConstantExpressionUnevaluated:
1028 case EM_EvaluateForOverflow:
1029 case EM_IgnoreSideEffects:
1032 case EM_ConstantExpression:
1033 case EM_ConstantExpressionUnevaluated:
1034 case EM_ConstantFold:
1037 llvm_unreachable(
"Missed EvalMode case");
1042 bool noteSideEffect() {
1044 return keepEvaluatingAfterSideEffect();
1048 bool keepEvaluatingAfterUndefinedBehavior() {
1050 case EM_EvaluateForOverflow:
1051 case EM_IgnoreSideEffects:
1052 case EM_ConstantFold:
1055 case EM_PotentialConstantExpression:
1056 case EM_PotentialConstantExpressionUnevaluated:
1057 case EM_ConstantExpression:
1058 case EM_ConstantExpressionUnevaluated:
1061 llvm_unreachable(
"Missed EvalMode case");
1067 bool noteUndefinedBehavior() {
1069 return keepEvaluatingAfterUndefinedBehavior();
1074 bool keepEvaluatingAfterFailure() {
1079 case EM_PotentialConstantExpression:
1080 case EM_PotentialConstantExpressionUnevaluated:
1081 case EM_EvaluateForOverflow:
1084 case EM_ConstantExpression:
1085 case EM_ConstantExpressionUnevaluated:
1086 case EM_ConstantFold:
1087 case EM_IgnoreSideEffects:
1090 llvm_unreachable(
"Missed EvalMode case");
1103 LLVM_NODISCARD
bool noteFailure() {
1111 bool KeepGoing = keepEvaluatingAfterFailure();
1116 class ArrayInitLoopIndex {
1118 uint64_t OuterIndex;
1121 ArrayInitLoopIndex(EvalInfo &Info)
1122 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1123 Info.ArrayInitIndex = 0;
1125 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1127 operator uint64_t&() {
return Info.ArrayInitIndex; }
1132 struct FoldConstant {
1135 bool HadNoPriorDiags;
1136 EvalInfo::EvaluationMode OldMode;
1138 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1141 HadNoPriorDiags(Info.EvalStatus.Diag &&
1142 Info.EvalStatus.Diag->empty() &&
1143 !Info.EvalStatus.HasSideEffects),
1144 OldMode(Info.EvalMode) {
1146 (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
1147 Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
1148 Info.EvalMode = EvalInfo::EM_ConstantFold;
1150 void keepDiagnostics() { Enabled =
false; }
1152 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1153 !Info.EvalStatus.HasSideEffects)
1154 Info.EvalStatus.Diag->clear();
1155 Info.EvalMode = OldMode;
1161 struct IgnoreSideEffectsRAII {
1163 EvalInfo::EvaluationMode OldMode;
1164 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1165 : Info(Info), OldMode(Info.EvalMode) {
1166 if (!Info.checkingPotentialConstantExpression())
1167 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1170 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1175 class SpeculativeEvaluationRAII {
1176 EvalInfo *Info =
nullptr;
1178 unsigned OldSpeculativeEvaluationDepth;
1180 void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
1182 OldStatus = Other.OldStatus;
1183 OldSpeculativeEvaluationDepth = Other.OldSpeculativeEvaluationDepth;
1184 Other.Info =
nullptr;
1187 void maybeRestoreState() {
1191 Info->EvalStatus = OldStatus;
1192 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1196 SpeculativeEvaluationRAII() =
default;
1198 SpeculativeEvaluationRAII(
1200 : Info(&Info), OldStatus(Info.EvalStatus),
1201 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1202 Info.EvalStatus.Diag = NewDiag;
1203 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1206 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &Other) =
delete;
1207 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&Other) {
1208 moveFromAndCancel(std::move(Other));
1211 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&Other) {
1212 maybeRestoreState();
1213 moveFromAndCancel(std::move(Other));
1217 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1222 template<
bool IsFullExpression>
1225 unsigned OldStackSize;
1227 ScopeRAII(EvalInfo &Info)
1228 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1231 Info.CurrentCall->pushTempVersion();
1237 Info.CurrentCall->popTempVersion();
1240 static void cleanup(EvalInfo &Info,
unsigned OldStackSize) {
1241 unsigned NewEnd = OldStackSize;
1242 for (
unsigned I = OldStackSize, N = Info.CleanupStack.size();
1244 if (IsFullExpression && Info.CleanupStack[I].isLifetimeExtended()) {
1247 std::swap(Info.CleanupStack[I], Info.CleanupStack[NewEnd]);
1251 Info.CleanupStack[I].endLifetime();
1254 Info.CleanupStack.erase(Info.CleanupStack.begin() + NewEnd,
1255 Info.CleanupStack.end());
1258 typedef ScopeRAII<false> BlockScopeRAII;
1259 typedef ScopeRAII<true> FullExpressionRAII;
1262 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1266 if (isOnePastTheEnd()) {
1267 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1278 void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1280 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1285 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1290 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1291 Info.CCEDiag(E, diag::note_constexpr_array_index)
1293 <<
static_cast<unsigned>(getMostDerivedArraySize());
1295 Info.CCEDiag(E, diag::note_constexpr_array_index)
1300 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
1303 : Info(Info), Caller(Info.CurrentCall), Callee(Callee), This(This),
1304 Arguments(Arguments), CallLoc(CallLoc), Index(Info.NextCallIndex++) {
1305 Info.CurrentCall =
this;
1306 ++Info.CallStackDepth;
1309 CallStackFrame::~CallStackFrame() {
1310 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1311 --Info.CallStackDepth;
1312 Info.CurrentCall = Caller;
1316 bool IsLifetimeExtended) {
1317 unsigned Version = Info.CurrentCall->getTempVersion();
1319 assert(Result.
isAbsent() &&
"temporary created multiple times");
1320 Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
1324 static void describeCall(CallStackFrame *Frame, raw_ostream &Out);
1326 void EvalInfo::addCallStack(
unsigned Limit) {
1328 unsigned ActiveCalls = CallStackDepth - 1;
1329 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
1330 if (Limit && Limit < ActiveCalls) {
1331 SkipStart = Limit / 2 + Limit % 2;
1332 SkipEnd = ActiveCalls - Limit / 2;
1336 unsigned CallIdx = 0;
1337 for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
1338 Frame = Frame->Caller, ++CallIdx) {
1340 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
1341 if (CallIdx == SkipStart) {
1343 addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
1344 << unsigned(ActiveCalls - Limit);
1351 if (
auto *CD = dyn_cast_or_null<CXXConstructorDecl>(Frame->Callee)) {
1352 if (CD->isInheritingConstructor()) {
1353 addDiag(Frame->CallLoc, diag::note_constexpr_inherited_ctor_call_here)
1360 llvm::raw_svector_ostream Out(Buffer);
1362 addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
1392 llvm_unreachable(
"unknown access kind");
1401 struct ComplexValue {
1406 APSInt IntReal, IntImag;
1407 APFloat FloatReal, FloatImag;
1409 ComplexValue() : FloatReal(APFloat::Bogus()), FloatImag(APFloat::Bogus()) {}
1411 void makeComplexFloat() { IsInt =
false; }
1412 bool isComplexFloat()
const {
return !IsInt; }
1413 APFloat &getComplexFloatReal() {
return FloatReal; }
1414 APFloat &getComplexFloatImag() {
return FloatImag; }
1416 void makeComplexInt() { IsInt =
true; }
1417 bool isComplexInt()
const {
return IsInt; }
1418 APSInt &getComplexIntReal() {
return IntReal; }
1419 APSInt &getComplexIntImag() {
return IntImag; }
1422 if (isComplexFloat())
1423 v =
APValue(FloatReal, FloatImag);
1425 v =
APValue(IntReal, IntImag);
1427 void setFrom(
const APValue &v) {
1446 bool InvalidBase : 1;
1451 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1452 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1453 bool isNullPointer()
const {
return IsNullPtr;}
1455 unsigned getLValueCallIndex()
const {
return Base.
getCallIndex(); }
1456 unsigned getLValueVersion()
const {
return Base.
getVersion(); }
1459 if (Designator.Invalid)
1462 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1463 V =
APValue(Base, Offset, Designator.Entries,
1464 Designator.IsOnePastTheEnd, IsNullPtr);
1468 assert(V.
isLValue() &&
"Setting LValue from a non-LValue?");
1471 InvalidBase =
false;
1472 Designator = SubobjectDesignator(Ctx, V);
1480 const auto *E = B.get<
const Expr *>();
1481 assert((isa<MemberExpr>(E) || tryUnwrapAllocSizeCall(E)) &&
1482 "Unexpected type of invalid base");
1488 InvalidBase = BInvalid;
1489 Designator = SubobjectDesignator(getType(B));
1493 void setNull(
QualType PointerTy, uint64_t TargetVal) {
1494 Base = (
Expr *)
nullptr;
1496 InvalidBase =
false;
1508 template <
typename GenDiagType>
1509 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1510 if (Designator.Invalid)
1514 Designator.setInvalid();
1521 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1523 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1524 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1528 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1530 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1531 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1538 return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
1539 Designator.checkSubobject(Info, E, CSK);
1542 void addDecl(EvalInfo &Info,
const Expr *E,
1543 const Decl *D,
bool Virtual =
false) {
1544 if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
1545 Designator.addDeclUnchecked(D, Virtual);
1547 void addUnsizedArray(EvalInfo &Info,
const Expr *E,
QualType ElemTy) {
1548 if (!Designator.Entries.empty()) {
1549 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1550 Designator.setInvalid();
1553 if (checkSubobject(Info, E, CSK_ArrayToPointer)) {
1554 assert(getType(Base)->isPointerType() || getType(Base)->isArrayType());
1555 Designator.FirstEntryIsAnUnsizedArray =
true;
1556 Designator.addUnsizedArrayUnchecked(ElemTy);
1560 if (checkSubobject(Info, E, CSK_ArrayToPointer))
1561 Designator.addArrayUnchecked(CAT);
1563 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1564 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1565 Designator.addComplexUnchecked(EltTy, Imag);
1567 void clearIsNullPointer() {
1570 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1571 const APSInt &Index,
CharUnits ElementSize) {
1582 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1585 if (checkNullPointer(Info, E, CSK_ArrayIndex))
1586 Designator.adjustIndex(Info, E, Index);
1587 clearIsNullPointer();
1592 clearIsNullPointer();
1599 DeclAndIsDerivedMember(Decl,
false), Path() {}
1604 return DeclAndIsDerivedMember.getPointer();
1607 bool isDerivedMember()
const {
1608 return DeclAndIsDerivedMember.getInt();
1612 return cast<CXXRecordDecl>(
1613 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1617 V =
APValue(getDecl(), isDerivedMember(), Path);
1619 void setFrom(
const APValue &V) {
1625 Path.insert(Path.end(), P.begin(), P.end());
1631 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1639 assert(!Path.empty());
1641 if (Path.size() >= 2)
1642 Expected = Path[Path.size() - 2];
1644 Expected = getContainingRecord();
1661 if (!isDerivedMember()) {
1662 Path.push_back(Derived);
1665 if (!castBack(Derived))
1668 DeclAndIsDerivedMember.setInt(
false);
1676 DeclAndIsDerivedMember.setInt(
true);
1677 if (isDerivedMember()) {
1678 Path.push_back(Base);
1681 return castBack(Base);
1686 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1687 if (!LHS.getDecl() || !RHS.getDecl())
1688 return !LHS.getDecl() && !RHS.getDecl();
1689 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1691 return LHS.Path == RHS.Path;
1697 const LValue &This,
const Expr *E,
1698 bool AllowNonLiteralTypes =
false);
1700 bool InvalidBaseOK =
false);
1702 bool InvalidBaseOK =
false);
1728 template <
class KeyTy>
1730 LValue &LV, CallStackFrame &Frame) {
1731 LV.set({Key, Frame.Info.CurrentCall->Index,
1732 Frame.Info.CurrentCall->getTempVersion()});
1733 return Frame.createTemporary(Key, IsLifetimeExtended);
1739 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1740 Int = Int.extend(Int.getBitWidth() + 1);
1741 Int.setIsSigned(
true);
1748 unsigned ArgIndex = 0;
1749 bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
1750 !isa<CXXConstructorDecl>(Frame->Callee) &&
1751 cast<CXXMethodDecl>(Frame->Callee)->isInstance();
1754 Out << *Frame->Callee <<
'(';
1756 if (Frame->This && IsMemberCall) {
1758 Frame->This->moveInto(Val);
1760 Frame->This->Designator.MostDerivedType);
1762 Out <<
"->" << *Frame->Callee <<
'(';
1763 IsMemberCall =
false;
1767 E = Frame->Callee->param_end(); I != E; ++I, ++ArgIndex) {
1768 if (ArgIndex > (
unsigned)IsMemberCall)
1772 const APValue &Arg = Frame->Arguments[ArgIndex];
1775 if (ArgIndex == 0 && IsMemberCall)
1776 Out <<
"->" << *Frame->Callee <<
'(';
1789 return Info.noteSideEffect();
1796 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1797 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1806 if (!B)
return true;
1810 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1811 return VD->hasGlobalStorage();
1813 return isa<FunctionDecl>(D);
1823 case Expr::CompoundLiteralExprClass: {
1827 case Expr::MaterializeTemporaryExprClass:
1830 return cast<MaterializeTemporaryExpr>(E)->getStorageDuration() ==
SD_Static;
1832 case Expr::StringLiteralClass:
1833 case Expr::PredefinedExprClass:
1834 case Expr::ObjCStringLiteralClass:
1835 case Expr::ObjCEncodeExprClass:
1836 case Expr::CXXUuidofExprClass:
1838 case Expr::ObjCBoxedExprClass:
1839 return cast<ObjCBoxedExpr>(E)->isExpressibleAsConstantInitializer();
1840 case Expr::CallExprClass:
1843 case Expr::AddrLabelExprClass:
1847 case Expr::BlockExprClass:
1848 return !cast<BlockExpr>(E)->getBlockDecl()->hasCaptures();
1849 case Expr::ImplicitValueInitExprClass:
1861 return LVal.Base.dyn_cast<
const ValueDecl*>();
1865 if (Value.getLValueCallIndex())
1867 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1868 return E && !isa<MaterializeTemporaryExpr>(E);
1873 return Decl && Decl->
isWeak();
1878 if (Decl && isa<VarDecl>(Decl)) {
1888 if (!A.getLValueBase())
1889 return !B.getLValueBase();
1890 if (!B.getLValueBase())
1893 if (A.getLValueBase().getOpaqueValue() !=
1894 B.getLValueBase().getOpaqueValue()) {
1904 (A.getLValueCallIndex() == B.getLValueCallIndex() &&
1905 A.getLValueVersion() == B.getLValueVersion());
1909 assert(Base &&
"no location for a null lvalue");
1912 Info.Note(VD->
getLocation(), diag::note_declared_at);
1914 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
1927 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
1933 if (Info.getLangOpts().CPlusPlus11) {
1935 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
1936 << IsReferenceType << !Designator.Entries.empty()
1945 assert((Info.checkingPotentialConstantExpression() ||
1946 LVal.getLValueCallIndex() == 0) &&
1947 "have call index for global lvalue");
1950 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
1952 if (Var->getTLSKind())
1959 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
1971 FD->hasAttr<DLLImportAttr>())
1978 if (!IsReferenceType)
1989 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
1991 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
1992 << !Designator.Entries.empty() << !!VD << VD;
2007 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
2011 !FD->hasAttr<DLLImportAttr>();
2017 const LValue *This =
nullptr) {
2034 if (This && Info.EvaluatingDecl == This->getLValueBase())
2038 if (Info.getLangOpts().CPlusPlus11)
2039 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2042 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2055 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2057 if (SubobjectLoc.isValid())
2058 Info.Note(SubobjectLoc, diag::note_constexpr_subobject_declared_here);
2065 Type = AT->getValueType();
2081 Usage, SubobjectLoc);
2091 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2092 unsigned BaseIndex = 0;
2101 for (
const auto *I : RD->
fields()) {
2102 if (I->isUnnamedBitfield())
2107 Usage, I->getLocation()))
2114 LVal.setFrom(Info.Ctx, Value);
2137 return !Decl || !Decl->
isWeak();
2146 Result = Val.
getInt().getBoolValue();
2175 llvm_unreachable(
"unknown APValue kind");
2180 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2187 template<
typename T>
2189 const T &SrcValue,
QualType DestType) {
2190 Info.CCEDiag(E, diag::note_constexpr_overflow)
2191 << SrcValue << DestType;
2192 return Info.noteUndefinedBehavior();
2196 QualType SrcType,
const APFloat &Value,
2197 QualType DestType, APSInt &Result) {
2198 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2202 Result = APSInt(DestWidth, !DestSigned);
2204 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2205 & APFloat::opInvalidOp)
2215 Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
2216 APFloat::rmNearestTiesToEven, &ignored);
2222 const APSInt &Value) {
2223 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2226 APSInt Result = Value.extOrTrunc(DestWidth);
2234 QualType SrcType,
const APSInt &Value,
2235 QualType DestType, APFloat &Result) {
2236 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2237 Result.convertFromAPInt(Value, Value.isSigned(),
2238 APFloat::rmNearestTiesToEven);
2244 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2246 if (!Value.
isInt()) {
2250 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
2255 APSInt &Int = Value.
getInt();
2256 unsigned OldBitWidth = Int.getBitWidth();
2258 if (NewBitWidth < OldBitWidth)
2259 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2273 Res = SVal.
getFloat().bitcastToAPInt();
2278 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
2280 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
2281 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
2282 Res = llvm::APInt::getNullValue(VecSize);
2285 llvm::APInt EltAsInt;
2289 EltAsInt = Elt.
getFloat().bitcastToAPInt();
2293 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2296 unsigned BaseEltSize = EltAsInt.getBitWidth();
2298 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(
i*EltSize+BaseEltSize);
2300 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(
i*EltSize);
2306 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2313 template<
typename Operation>
2315 const APSInt &LHS,
const APSInt &RHS,
2316 unsigned BitWidth, Operation Op,
2318 if (LHS.isUnsigned()) {
2319 Result = Op(LHS, RHS);
2323 APSInt
Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2324 Result = Value.trunc(LHS.getBitWidth());
2325 if (Result.extend(BitWidth) !=
Value) {
2326 if (Info.checkingForOverflow())
2327 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2328 diag::warn_integer_constant_overflow)
2329 << Result.toString(10) << E->
getType();
2346 std::multiplies<APSInt>(), Result);
2349 std::plus<APSInt>(), Result);
2352 std::minus<APSInt>(), Result);
2353 case BO_And: Result = LHS & RHS;
return true;
2354 case BO_Xor: Result = LHS ^ RHS;
return true;
2355 case BO_Or: Result = LHS | RHS;
return true;
2359 Info.FFDiag(E, diag::note_expr_divide_by_zero);
2362 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2365 if (RHS.isNegative() && RHS.isAllOnesValue() &&
2366 LHS.isSigned() && LHS.isMinSignedValue())
2367 return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
2371 if (Info.getLangOpts().OpenCL)
2373 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2374 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2376 else if (RHS.isSigned() && RHS.isNegative()) {
2379 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2386 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2388 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2389 << RHS << E->
getType() << LHS.getBitWidth();
2390 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus2a) {
2395 if (LHS.isNegative())
2396 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2397 else if (LHS.countLeadingZeros() < SA)
2398 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2404 if (Info.getLangOpts().OpenCL)
2406 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2407 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2409 else if (RHS.isSigned() && RHS.isNegative()) {
2412 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2419 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2421 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2422 << RHS << E->
getType() << LHS.getBitWidth();
2427 case BO_LT: Result = LHS < RHS;
return true;
2428 case BO_GT: Result = LHS > RHS;
return true;
2429 case BO_LE: Result = LHS <= RHS;
return true;
2430 case BO_GE: Result = LHS >= RHS;
return true;
2431 case BO_EQ: Result = LHS == RHS;
return true;
2432 case BO_NE: Result = LHS != RHS;
return true;
2434 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2441 const APFloat &RHS) {
2447 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
2450 LHS.add(RHS, APFloat::rmNearestTiesToEven);
2453 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
2459 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2460 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
2469 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2470 return Info.noteUndefinedBehavior();
2479 unsigned TruncatedElements) {
2480 SubobjectDesignator &D = Result.Designator;
2483 if (TruncatedElements == D.Entries.size())
2485 assert(TruncatedElements >= D.MostDerivedPathLength &&
2486 "not casting to a derived class");
2487 if (!Result.checkSubobject(Info, E, CSK_Derived))
2492 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
2496 if (isVirtualBaseClass(D.Entries[I]))
2502 D.Entries.resize(TruncatedElements);
2512 RL = &Info.Ctx.getASTRecordLayout(Derived);
2515 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
2516 Obj.addDecl(Info, E, Base,
false);
2528 SubobjectDesignator &D = Obj.Designator;
2533 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
2539 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
2541 Obj.addDecl(Info, E, BaseDecl,
true);
2549 PathI != PathE; ++PathI) {
2553 Type = (*PathI)->getType();
2565 llvm_unreachable(
"Class must be derived from the passed in base class!");
2580 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
2584 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
2585 LVal.addDecl(Info, E, FD);
2593 for (
const auto *
C : IFD->
chain())
2621 Size = Info.Ctx.getTypeSizeInChars(Type);
2633 APSInt Adjustment) {
2638 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
2644 int64_t Adjustment) {
2646 APSInt::get(Adjustment));
2661 LVal.Offset += SizeOfComponent;
2663 LVal.addComplex(Info, E, EltTy, Imag);
2676 const VarDecl *VD, CallStackFrame *Frame,
2677 APValue *&Result,
const LValue *LVal) {
2681 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
2684 if (Info.checkingPotentialConstantExpression())
2686 if (!Frame || !Frame->Arguments) {
2687 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2690 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
2696 Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion())
2697 : Frame->getCurrentTemporary(VD);
2705 "missing value for local variable");
2706 if (Info.checkingPotentialConstantExpression())
2710 diag::note_unimplemented_constexpr_lambda_feature_ast)
2711 <<
"captures not currently allowed";
2722 if (!Info.checkingPotentialConstantExpression())
2723 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2729 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
2730 Result = Info.EvaluatingDeclValue;
2737 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2745 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant,
2746 Notes.size() + 1) << VD;
2747 Info.Note(VD->
getLocation(), diag::note_declared_at);
2748 Info.addNotes(Notes);
2751 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2752 Notes.size() + 1) << VD;
2753 Info.Note(VD->
getLocation(), diag::note_declared_at);
2754 Info.addNotes(Notes);
2773 E = Derived->
bases_end(); I != E; ++I, ++Index) {
2774 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2778 llvm_unreachable(
"base class missing from derived class's bases list");
2784 assert(!isa<SourceLocExpr>(Lit) &&
2785 "SourceLocExpr should have already been converted to a StringLiteral");
2788 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
2790 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
2791 assert(Index <= Str.size() &&
"Index too large");
2792 return APSInt::getUnsigned(Str.c_str()[Index]);
2795 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2796 Lit = PE->getFunctionName();
2799 Info.Ctx.getAsConstantArrayType(S->
getType());
2800 assert(CAT &&
"string literal isn't an array");
2801 QualType CharType = CAT->getElementType();
2802 assert(CharType->
isIntegerType() &&
"unexpected character type");
2806 if (Index < S->getLength())
2818 Info.Ctx.getAsConstantArrayType(S->
getType());
2819 assert(CAT &&
"string literal isn't an array");
2821 assert(CharType->
isIntegerType() &&
"unexpected character type");
2823 unsigned Elts = CAT->
getSize().getZExtValue();
2839 assert(Index < Size);
2843 unsigned NewElts =
std::max(Index+1, OldElts * 2);
2848 for (
unsigned I = 0; I != OldElts; ++I)
2850 for (
unsigned I = OldElts; I != NewElts; ++I)
2854 Array.
swap(NewValue);
2869 for (
auto *Field : RD->
fields())
2873 for (
auto &BaseSpec : RD->
bases())
2891 for (
auto *Field : RD->
fields()) {
2896 if (Field->isMutable() &&
2898 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field;
2899 Info.Note(Field->getLocation(), diag::note_declared_at);
2907 for (
auto &BaseSpec : RD->
bases())
2921 auto *Evaluating = Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>();
2933 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
2943 struct CompleteObject {
2951 CompleteObject() :
Value(
nullptr) {}
2953 : Base(Base),
Value(Value), Type(Type) {}
2955 bool mayReadMutableMembers(EvalInfo &Info)
const {
2959 if (!Info.getLangOpts().CPlusPlus14)
2964 explicit operator bool()
const {
return !Type.
isNull(); }
2969 bool IsMutable =
false) {
2983 template<
typename Sub
objectHandler>
2984 typename SubobjectHandler::result_type
2986 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
2989 return handler.failed();
2990 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
2991 if (Info.getLangOpts().CPlusPlus11)
2992 Info.FFDiag(E, Sub.isOnePastTheEnd()
2993 ? diag::note_constexpr_access_past_end
2994 : diag::note_constexpr_access_unsized_array)
2995 << handler.AccessKind;
2998 return handler.failed();
3004 const FieldDecl *VolatileField =
nullptr;
3007 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
3010 if (!Info.checkingPotentialConstantExpression())
3011 Info.FFDiag(E, diag::note_constexpr_access_uninit)
3013 return handler.failed();
3021 Info.isEvaluatingConstructor(
3022 Obj.Base, llvm::makeArrayRef(Sub.Entries.begin(),
3023 Sub.Entries.begin() + I)) !=
3025 ObjType = Info.Ctx.getCanonicalType(ObjType);
3034 if (Info.getLangOpts().CPlusPlus) {
3038 if (VolatileField) {
3041 Decl = VolatileField;
3042 }
else if (
auto *VD = Obj.Base.dyn_cast<
const ValueDecl*>()) {
3044 Loc = VD->getLocation();
3048 if (
auto *E = Obj.Base.dyn_cast<
const Expr *>())
3051 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3052 << handler.AccessKind << DiagKind << Decl;
3053 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
3055 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3057 return handler.failed();
3065 !Obj.mayReadMutableMembers(Info) &&
3067 return handler.failed();
3071 if (!handler.found(*O, ObjType))
3083 LastField =
nullptr;
3087 assert(CAT &&
"vla in literal type?");
3088 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3089 if (CAT->
getSize().ule(Index)) {
3092 if (Info.getLangOpts().CPlusPlus11)
3093 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3094 << handler.AccessKind;
3097 return handler.failed();
3104 else if (handler.AccessKind !=
AK_Read) {
3111 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
3113 if (Info.getLangOpts().CPlusPlus11)
3114 Info.FFDiag(E, diag::note_constexpr_access_past_end)
3115 << handler.AccessKind;
3118 return handler.failed();
3124 assert(I == N - 1 &&
"extracting subobject of scalar?");
3133 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
3134 if (Field->isMutable() && handler.AccessKind ==
AK_Read &&
3135 !Obj.mayReadMutableMembers(Info)) {
3136 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1)
3138 Info.Note(Field->getLocation(), diag::note_declared_at);
3139 return handler.failed();
3148 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
3149 << handler.AccessKind << Field << !UnionField << UnionField;
3150 return handler.failed();
3158 if (Field->getType().isVolatileQualified())
3159 VolatileField = Field;
3172 struct ExtractSubobjectHandler {
3178 typedef bool result_type;
3179 bool failed() {
return false; }
3184 bool found(APSInt &Value,
QualType SubobjType) {
3188 bool found(APFloat &Value,
QualType SubobjType) {
3199 const CompleteObject &Obj,
3200 const SubobjectDesignator &Sub,
3202 ExtractSubobjectHandler Handler = { Info, Result };
3207 struct ModifySubobjectHandler {
3212 typedef bool result_type;
3218 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3224 bool failed() {
return false; }
3226 if (!checkConst(SubobjType))
3229 Subobj.
swap(NewVal);
3232 bool found(APSInt &Value,
QualType SubobjType) {
3233 if (!checkConst(SubobjType))
3235 if (!NewVal.
isInt()) {
3243 bool found(APFloat &Value,
QualType SubobjType) {
3244 if (!checkConst(SubobjType))
3256 const CompleteObject &Obj,
3257 const SubobjectDesignator &Sub,
3259 ModifySubobjectHandler Handler = { Info, NewVal, E };
3266 const SubobjectDesignator &A,
3267 const SubobjectDesignator &B,
3268 bool &WasArrayIndex) {
3269 unsigned I = 0, N =
std::min(A.Entries.size(), B.Entries.size());
3270 for (; I != N; ++I) {
3274 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
3275 WasArrayIndex =
true;
3283 if (A.Entries[I].getAsBaseOrMember() !=
3284 B.Entries[I].getAsBaseOrMember()) {
3285 WasArrayIndex =
false;
3288 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
3290 ObjType = FD->getType();
3296 WasArrayIndex =
false;
3303 const SubobjectDesignator &A,
3304 const SubobjectDesignator &B) {
3305 if (A.Entries.size() != B.Entries.size())
3308 bool IsArray = A.MostDerivedIsArrayElement;
3309 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
3318 return CommonLength >= A.Entries.size() - IsArray;
3325 if (LVal.InvalidBase) {
3327 return CompleteObject();
3331 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
3332 return CompleteObject();
3335 CallStackFrame *Frame =
nullptr;
3337 if (LVal.getLValueCallIndex()) {
3338 std::tie(Frame, Depth) =
3339 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
3341 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
3342 << AK << LVal.Base.is<
const ValueDecl*>();
3344 return CompleteObject();
3355 if (Info.getLangOpts().CPlusPlus)
3356 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
3360 return CompleteObject();
3365 QualType BaseType = getType(LVal.Base);
3382 return CompleteObject();
3388 if (Info.getLangOpts().CPlusPlus14 &&
3390 VD, Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>())) {
3396 Info.FFDiag(E, diag::note_constexpr_modify_global);
3397 return CompleteObject();
3404 (Info.getLangOpts().OpenCL &&
3407 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3408 if (Info.getLangOpts().CPlusPlus) {
3409 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
3410 Info.Note(VD->
getLocation(), diag::note_declared_at);
3414 return CompleteObject();
3416 }
else if (!IsAccess) {
3417 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3422 if (Info.getLangOpts().CPlusPlus11) {
3423 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3424 Info.Note(VD->
getLocation(), diag::note_declared_at);
3429 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD;
3433 if (Info.checkingPotentialConstantExpression() &&
3437 }
else if (Info.getLangOpts().CPlusPlus11) {
3438 Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3439 Info.Note(VD->
getLocation(), diag::note_declared_at);
3443 return CompleteObject();
3448 return CompleteObject();
3450 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3454 dyn_cast_or_null<MaterializeTemporaryExpr>(Base)) {
3455 assert(MTE->getStorageDuration() ==
SD_Static &&
3456 "should have a frame for a non-global materialized temporary");
3473 const ValueDecl *ED = MTE->getExtendingDecl();
3476 !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) {
3478 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3479 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
3480 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
3481 return CompleteObject();
3484 BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE,
false);
3485 assert(BaseVal &&
"got reference to unevaluated temporary");
3488 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
3491 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
3493 << Val.getAsString(Info.Ctx,
3494 Info.Ctx.getLValueReferenceType(LValType));
3496 return CompleteObject();
3499 BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion());
3500 assert(BaseVal &&
"missing value for temporary");
3509 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
3510 Info.EvalStatus.HasSideEffects) ||
3512 return CompleteObject();
3514 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
3530 const LValue &LVal,
APValue &RVal) {
3531 if (LVal.Designator.Invalid)
3535 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3547 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
3549 CompleteObject LitObj(LVal.Base, &Lit, Base->
getType());
3551 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
3554 assert(LVal.Designator.Entries.size() <= 1 &&
3555 "Can only read characters from string literals");
3556 if (LVal.Designator.Entries.empty()) {
3563 if (LVal.Designator.isOnePastTheEnd()) {
3564 if (Info.getLangOpts().CPlusPlus11)
3565 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) <<
AK_Read;
3570 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
3583 if (LVal.Designator.Invalid)
3586 if (!Info.getLangOpts().CPlusPlus14) {
3596 struct CompoundAssignSubobjectHandler {
3605 typedef bool result_type;
3610 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3616 bool failed() {
return false; }
3620 return found(Subobj.
getInt(), SubobjType);
3622 return found(Subobj.
getFloat(), SubobjType);
3629 return foundPointer(Subobj, SubobjType);
3636 bool found(APSInt &Value,
QualType SubobjType) {
3637 if (!checkConst(SubobjType))
3655 APFloat FValue(0.0);
3666 bool found(APFloat &Value,
QualType SubobjType) {
3667 return checkConst(SubobjType) &&
3674 if (!checkConst(SubobjType))
3682 (Opcode != BO_Add && Opcode != BO_Sub)) {
3688 if (Opcode == BO_Sub)
3692 LVal.setFrom(Info.Ctx, Subobj);
3695 LVal.moveInto(Subobj);
3705 EvalInfo &Info,
const Expr *E,
3708 if (LVal.Designator.Invalid)
3711 if (!Info.getLangOpts().CPlusPlus14) {
3717 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
3719 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3723 struct IncDecSubobjectHandler {
3729 typedef bool result_type;
3734 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3740 bool failed() {
return false; }
3751 return found(Subobj.
getInt(), SubobjType);
3753 return found(Subobj.
getFloat(), SubobjType);
3763 return foundPointer(Subobj, SubobjType);
3770 bool found(APSInt &Value,
QualType SubobjType) {
3771 if (!checkConst(SubobjType))
3781 if (Old) *Old =
APValue(Value);
3793 bool WasNegative = Value.isNegative();
3797 if (!WasNegative && Value.isNegative() && E->
canOverflow()) {
3798 APSInt ActualValue(Value,
true);
3804 if (WasNegative && !Value.isNegative() && E->
canOverflow()) {
3805 unsigned BitWidth = Value.getBitWidth();
3806 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
3807 ActualValue.setBit(BitWidth);
3813 bool found(APFloat &Value,
QualType SubobjType) {
3814 if (!checkConst(SubobjType))
3817 if (Old) *Old =
APValue(Value);
3819 APFloat One(Value.getSemantics(), 1);
3821 Value.add(One, APFloat::rmNearestTiesToEven);
3823 Value.subtract(One, APFloat::rmNearestTiesToEven);
3827 if (!checkConst(SubobjType))
3839 LVal.setFrom(Info.Ctx, Subobj);
3843 LVal.moveInto(Subobj);
3852 if (LVal.Designator.Invalid)
3855 if (!Info.getLangOpts().CPlusPlus14) {
3862 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(E), AK, Old};
3863 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3878 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
3897 bool IncludeMember =
true) {
3904 if (!MemPtr.getDecl()) {
3910 if (MemPtr.isDerivedMember()) {
3914 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
3915 LV.Designator.Entries.size()) {
3919 unsigned PathLengthToMember =
3920 LV.Designator.Entries.size() - MemPtr.Path.size();
3921 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
3923 LV.Designator.Entries[PathLengthToMember + I]);
3933 PathLengthToMember))
3935 }
else if (!MemPtr.Path.empty()) {
3937 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
3938 MemPtr.Path.size() + IncludeMember);
3944 assert(RD &&
"member pointer access on non-class-type expression");
3946 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
3954 MemPtr.getContainingRecord()))
3959 if (IncludeMember) {
3960 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
3964 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
3968 llvm_unreachable(
"can't construct reference to bound member function");
3972 return MemPtr.getDecl();
3978 bool IncludeMember =
true) {
3982 if (Info.noteFailure()) {
3990 BO->
getRHS(), IncludeMember);
3997 SubobjectDesignator &D = Result.Designator;
3998 if (D.Invalid || !Result.checkNullPointer(Info, E, CSK_Derived))
4006 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
4007 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4008 << D.MostDerivedType << TargetQT;
4014 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
4017 if (NewEntriesSize == D.MostDerivedPathLength)
4018 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
4020 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
4022 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
4023 << D.MostDerivedType << TargetQT;
4058 Info.FFDiag(VD->
getBeginLoc(), diag::note_constexpr_uninitialized)
4080 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
4084 for (
auto *BD : DD->bindings())
4085 if (
auto *VD = BD->getHoldingVar())
4094 const Expr *Cond,
bool &Result) {
4095 FullExpressionRAII
Scope(Info);
4111 struct TempVersionRAII {
4112 CallStackFrame &Frame;
4114 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
4115 Frame.pushTempVersion();
4118 ~TempVersionRAII() {
4119 Frame.popTempVersion();
4133 BlockScopeRAII
Scope(Info);
4136 return ESR_Succeeded;
4139 return ESR_Continue;
4142 case ESR_CaseNotFound:
4145 llvm_unreachable(
"Invalid EvalStmtResult!");
4151 BlockScopeRAII
Scope(Info);
4156 FullExpressionRAII Scope(Info);
4159 if (ESR != ESR_Succeeded)
4174 if (isa<DefaultStmt>(SC)) {
4179 const CaseStmt *CS = cast<CaseStmt>(SC);
4183 if (LHS <= Value && Value <= RHS) {
4190 return ESR_Succeeded;
4195 return ESR_Succeeded;
4201 case ESR_CaseNotFound:
4205 diag::note_constexpr_stmt_expr_unsupported);
4208 llvm_unreachable(
"Invalid EvalStmtResult!");
4214 if (!Info.nextStep(S))
4225 case Stmt::CompoundStmtClass:
4229 case Stmt::LabelStmtClass:
4230 case Stmt::AttributedStmtClass:
4231 case Stmt::DoStmtClass:
4234 case Stmt::CaseStmtClass:
4235 case Stmt::DefaultStmtClass:
4240 case Stmt::IfStmtClass: {
4243 const IfStmt *IS = cast<IfStmt>(S);
4247 BlockScopeRAII
Scope(Info);
4250 if (ESR != ESR_CaseNotFound || !IS->
getElse())
4255 case Stmt::WhileStmtClass: {
4258 if (ESR != ESR_Continue)
4263 case Stmt::ForStmtClass: {
4264 const ForStmt *FS = cast<ForStmt>(S);
4267 if (ESR != ESR_Continue)
4270 FullExpressionRAII IncScope(Info);
4277 case Stmt::DeclStmtClass:
4281 return ESR_CaseNotFound;
4287 if (
const Expr *E = dyn_cast<Expr>(S)) {
4290 FullExpressionRAII
Scope(Info);
4293 return ESR_Succeeded;
4299 case Stmt::NullStmtClass:
4300 return ESR_Succeeded;
4302 case Stmt::DeclStmtClass: {
4303 const DeclStmt *DS = cast<DeclStmt>(S);
4304 for (
const auto *DclIt : DS->
decls()) {
4308 FullExpressionRAII
Scope(Info);
4312 return ESR_Succeeded;
4315 case Stmt::ReturnStmtClass: {
4316 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
4317 FullExpressionRAII
Scope(Info);
4320 ? EvaluateInPlace(Result.Value, Info, *Result.Slot, RetExpr)
4321 : Evaluate(Result.Value, Info, RetExpr)))
4323 return ESR_Returned;
4326 case Stmt::CompoundStmtClass: {
4327 BlockScopeRAII
Scope(Info);
4330 for (
const auto *BI : CS->
body()) {
4332 if (ESR == ESR_Succeeded)
4334 else if (ESR != ESR_CaseNotFound)
4337 return Case ? ESR_CaseNotFound : ESR_Succeeded;
4340 case Stmt::IfStmtClass: {
4341 const IfStmt *IS = cast<IfStmt>(S);
4344 BlockScopeRAII
Scope(Info);
4347 if (ESR != ESR_Succeeded)
4356 if (ESR != ESR_Succeeded)
4359 return ESR_Succeeded;
4362 case Stmt::WhileStmtClass: {
4363 const WhileStmt *WS = cast<WhileStmt>(S);
4365 BlockScopeRAII
Scope(Info);
4374 if (ESR != ESR_Continue)
4377 return ESR_Succeeded;
4380 case Stmt::DoStmtClass: {
4381 const DoStmt *DS = cast<DoStmt>(S);
4385 if (ESR != ESR_Continue)
4389 FullExpressionRAII CondScope(Info);
4393 return ESR_Succeeded;
4396 case Stmt::ForStmtClass: {
4397 const ForStmt *FS = cast<ForStmt>(S);
4398 BlockScopeRAII
Scope(Info);
4401 if (ESR != ESR_Succeeded)
4405 BlockScopeRAII Scope(Info);
4406 bool Continue =
true;
4414 if (ESR != ESR_Continue)
4418 FullExpressionRAII IncScope(Info);
4423 return ESR_Succeeded;
4426 case Stmt::CXXForRangeStmtClass: {
4428 BlockScopeRAII
Scope(Info);
4433 if (ESR != ESR_Succeeded)
4439 if (ESR != ESR_Succeeded)
4444 if (ESR != ESR_Succeeded)
4447 if (ESR != ESR_Succeeded)
4453 bool Continue =
true;
4454 FullExpressionRAII CondExpr(Info);
4462 BlockScopeRAII InnerScope(Info);
4464 if (ESR != ESR_Succeeded)
4469 if (ESR != ESR_Continue)
4477 return ESR_Succeeded;
4480 case Stmt::SwitchStmtClass:
4483 case Stmt::ContinueStmtClass:
4484 return ESR_Continue;
4486 case Stmt::BreakStmtClass:
4489 case Stmt::LabelStmtClass:
4490 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
4492 case Stmt::AttributedStmtClass:
4495 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
4498 case Stmt::CaseStmtClass:
4499 case Stmt::DefaultStmtClass:
4500 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
4501 case Stmt::CXXTryStmtClass:
4503 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
4513 bool IsValueInitialization) {
4520 if (!CD->
isConstexpr() && !IsValueInitialization) {
4521 if (Info.getLangOpts().CPlusPlus11) {
4524 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
4526 Info.Note(CD->
getLocation(), diag::note_declared_at);
4528 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
4542 if (Info.checkingPotentialConstantExpression() && !Definition &&
4550 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4557 if (!Info.Ctx.getLangOpts().CPlusPlus2a && isa<CXXMethodDecl>(Declaration) &&
4558 cast<CXXMethodDecl>(Declaration)->isVirtual())
4559 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
4562 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4567 if (Definition && Definition->
isConstexpr() && Body)
4570 if (Info.getLangOpts().CPlusPlus11) {
4571 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
4576 if (CD && CD->isInheritingConstructor()) {
4578 if (!Inherited->isConstexpr())
4579 DiagDecl = CD = Inherited;
4585 if (CD && CD->isInheritingConstructor())
4586 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
4587 << CD->getInheritedConstructor().getConstructor()->getParent();
4589 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
4591 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
4593 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4599 struct CheckDynamicTypeHandler {
4601 typedef bool result_type;
4602 bool failed() {
return false; }
4604 bool found(APSInt &Value,
QualType SubobjType) {
return true; }
4605 bool found(APFloat &Value,
QualType SubobjType) {
return true; }
4613 if (This.Designator.Invalid)
4625 if (This.Designator.isOnePastTheEnd() ||
4626 This.Designator.isMostDerivedAnUnsizedArray()) {
4627 Info.FFDiag(E, This.Designator.isOnePastTheEnd()
4628 ? diag::note_constexpr_access_past_end
4629 : diag::note_constexpr_access_unsized_array)
4632 }
else if (Polymorphic) {
4638 Info.Ctx.getLValueReferenceType(This.Designator.getType(Info.Ctx));
4639 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
4646 CheckDynamicTypeHandler Handler{AK};
4647 return Obj &&
findSubobject(Info, E, Obj, This.Designator, Handler);
4653 const LValue &This) {
4665 unsigned PathLength) {
4666 assert(PathLength >= Designator.MostDerivedPathLength && PathLength <=
4667 Designator.Entries.size() &&
"invalid path length");
4668 return (PathLength == Designator.MostDerivedPathLength)
4669 ? Designator.MostDerivedType->getAsCXXRecordDecl()
4670 : getAsBaseClass(Designator.Entries[PathLength - 1]);
4689 This.Designator.MostDerivedType->getAsCXXRecordDecl();
4700 for (
unsigned PathLength = This.Designator.MostDerivedPathLength;
4701 PathLength <= Path.size(); ++PathLength) {
4702 switch (Info.isEvaluatingConstructor(This.getLValueBase(),
4703 Path.slice(0, PathLength))) {
4704 case ConstructionPhase::Bases:
4709 case ConstructionPhase::AfterBases:
4738 unsigned PathLength = DynType->PathLength;
4739 for (; PathLength <= This.Designator.Entries.size(); ++PathLength) {
4753 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
4754 Info.Note(Callee->
getLocation(), diag::note_declared_at);
4760 if (!Info.Ctx.hasSameUnqualifiedType(Callee->
getReturnType(),
4763 for (
unsigned CovariantPathLength = PathLength + 1;
4764 CovariantPathLength != This.Designator.Entries.size();
4765 ++CovariantPathLength) {
4770 if (Next && !Info.Ctx.hasSameUnqualifiedType(
4774 if (!Info.Ctx.hasSameUnqualifiedType(Found->
getReturnType(),
4775 CovariantAdjustmentPath.back()))
4793 "unexpected kind of APValue for covariant return");
4798 LVal.setFrom(Info.Ctx, Result);
4800 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
4801 for (
unsigned I = 1; I != Path.size(); ++I) {
4802 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
4803 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
4804 if (OldClass != NewClass &&
4807 OldClass = NewClass;
4810 LVal.moveInto(Result);
4819 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
4821 return BaseSpec.getAccessSpecifier() ==
AS_public;
4823 llvm_unreachable(
"Base is not a direct base of Derived");
4833 SubobjectDesignator &D = Ptr.Designator;
4839 if (Ptr.isNullPointer() && !E->
isGLValue())
4857 assert(C &&
"dynamic_cast target is not void pointer nor class");
4858 CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(C));
4865 auto TargetVal = Info.Ctx.getTargetNullPointerValue(E->
getType());
4866 Ptr.setNull(E->
getType(), TargetVal);
4873 DynType->Type->isDerivedFrom(C)))
4875 else if (!Paths || Paths->begin() == Paths->end())
4877 else if (Paths->isAmbiguous(CQT))
4880 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
4883 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
4884 << DiagKind << Ptr.Designator.getType(Info.Ctx)
4885 << Info.Ctx.getRecordType(DynType->Type)
4893 for (
int PathLength = Ptr.Designator.Entries.size();
4894 PathLength >= (int)DynType->PathLength; --PathLength) {
4899 if (PathLength > (
int)DynType->PathLength &&
4902 return RuntimeCheckFailed(
nullptr);
4909 if (DynType->Type->isDerivedFrom(C, Paths) && !Paths.
isAmbiguous(CQT) &&
4922 return RuntimeCheckFailed(&Paths);
4926 struct StartLifetimeOfUnionMemberHandler {
4941 End = RD->bases_end(); I !=
End; ++I, ++Index)
4942 Struct.
getStructBase(Index) = getDefaultInitValue(I->getType());
4944 for (
const auto *I : RD->fields()) {
4945 if (I->isUnnamedBitfield())
4948 getDefaultInitValue(I->getType());
4953 if (
auto *AT = dyn_cast_or_null<ConstantArrayType>(
4956 if (Array.hasArrayFiller())
4964 typedef bool result_type;
4965 bool failed() {
return false; }
4980 bool found(APSInt &Value,
QualType SubobjType) {
4981 llvm_unreachable(
"wrong value kind for union object");
4983 bool found(APFloat &Value,
QualType SubobjType) {
4984 llvm_unreachable(
"wrong value kind for union object");
4996 const LValue &LHS) {
4997 if (LHS.InvalidBase || LHS.Designator.Invalid)
5003 unsigned PathLength = LHS.Designator.Entries.size();
5004 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
5006 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
5007 auto *FD = dyn_cast<
FieldDecl>(ME->getMemberDecl());
5012 if (FD->getParent()->isUnion())
5013 UnionPathLengths.push_back({PathLength - 1, FD});
5018 LHS.Designator.Entries[PathLength]
5019 .getAsBaseOrMember().getPointer()));
5023 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
5025 auto *Base = ASE->getBase()->IgnoreImplicit();
5026 if (!Base->getType()->isArrayType())
5032 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
5034 E = ICE->getSubExpr();
5035 if (ICE->getCastKind() == CK_NoOp)
5037 if (ICE->getCastKind() != CK_DerivedToBase &&
5038 ICE->getCastKind() != CK_UncheckedDerivedToBase)
5045 LHS.Designator.Entries[PathLength]
5046 .getAsBaseOrMember().getPointer()));
5056 if (UnionPathLengths.empty())
5061 CompleteObject Obj =
5065 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
5066 llvm::reverse(UnionPathLengths)) {
5068 SubobjectDesignator D = LHS.Designator;
5069 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
5071 StartLifetimeOfUnionMemberHandler StartLifetime{LengthAndField.second};
5084 for (
auto *FD : RD->
fields()) {
5085 if (FD->isUnnamedBitfield())
5089 for (
auto &Base : RD->
bases())
5090 if (
hasFields(Base.getType()->getAsCXXRecordDecl()))
5102 bool Success =
true;
5103 llvm::SmallBitVector ForbiddenNullArgs;
5104 if (Callee->
hasAttr<NonNullAttr>()) {
5105 ForbiddenNullArgs.resize(Args.size());
5107 if (!
Attr->args_size()) {
5108 ForbiddenNullArgs.set();
5111 for (
auto Idx :
Attr->args()) {
5112 unsigned ASTIdx = Idx.getASTIndex();
5113 if (ASTIdx >= Args.size())
5115 ForbiddenNullArgs[ASTIdx] = 1;
5121 if (!
Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
5124 if (!Info.noteFailure())
5127 }
else if (!ForbiddenNullArgs.empty() &&
5128 ForbiddenNullArgs[I - Args.begin()] &&
5129 ArgValues[I - Args.begin()].isNullPointer()) {
5130 Info.CCEDiag(*I, diag::note_non_null_attribute_failed);
5131 if (!Info.noteFailure())
5143 EvalInfo &Info,
APValue &Result,
5144 const LValue *ResultSlot) {
5145 ArgVector ArgValues(Args.size());
5149 if (!Info.CheckCallLimit(CallLoc))
5152 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
5161 if (MD && MD->isDefaulted() &&
5162 (MD->getParent()->isUnion() ||
5163 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
5165 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
5167 RHS.setFrom(Info.Ctx, ArgValues[0]);
5172 if (Info.getLangOpts().CPlusPlus2a && MD->isTrivial() &&
5178 This->moveInto(Result);
5187 if (!Info.checkingPotentialConstantExpression())
5188 MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
5189 Frame.LambdaThisCaptureField);
5194 if (ESR == ESR_Succeeded) {
5197 Info.FFDiag(Callee->
getEndLoc(), diag::note_constexpr_no_return);
5199 return ESR == ESR_Returned;
5206 EvalInfo &Info,
APValue &Result) {
5208 if (!Info.CheckCallLimit(CallLoc))
5213 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
5217 EvalInfo::EvaluatingConstructorRAII EvalObj(
5219 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
5221 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
5232 FullExpressionRAII InitScope(Info);
5251 RHS.setFrom(Info.Ctx, ArgValues[0]);
5266 BlockScopeRAII LifetimeExtendedScope(Info);
5268 bool Success =
true;
5269 unsigned BasesSeen = 0;
5273 for (
const auto *I : Definition->
inits()) {
5274 LValue Subobject = This;
5275 LValue SubobjectParent = This;
5280 if (I->isBaseInitializer()) {
5281 QualType BaseType(I->getBaseClass(), 0);
5285 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
5286 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
5287 "base class initializers not in expected order");
5291 BaseType->getAsCXXRecordDecl(), &Layout))
5294 }
else if ((FD = I->getMember())) {
5306 auto IndirectFieldChain = IFD->chain();
5307 for (
auto *
C : IndirectFieldChain) {
5308 FD = cast<FieldDecl>(
C);
5325 if (
C == IndirectFieldChain.back())
5326 SubobjectParent = Subobject;
5335 llvm_unreachable(
"unknown base initializer kind");
5341 const Expr *Init = I->getInit();
5342 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
5343 isa<CXXDefaultInitExpr>(Init));
5344 FullExpressionRAII InitScope(Info);
5350 if (!Info.noteFailure())
5357 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
5358 EvalObj.finishedConstructingBases();
5368 EvalInfo &Info,
APValue &Result) {
5369 ArgVector ArgValues(Args.size());
5382 class BitCastBuffer {
5390 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
5391 "Need at least 8 bit unsigned char");
5393 bool TargetIsLittleEndian;
5396 BitCastBuffer(
CharUnits Width,
bool TargetIsLittleEndian)
5398 TargetIsLittleEndian(TargetIsLittleEndian) {}
5403 for (
CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
5406 if (!Bytes[I.getQuantity()])
5408 Output.push_back(*Bytes[I.getQuantity()]);
5410 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
5411 std::reverse(Output.begin(), Output.end());
5416 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
5417 std::reverse(Input.begin(), Input.end());
5420 for (
unsigned char Byte : Input) {
5421 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
5427 size_t size() {
return Bytes.size(); }
5432 class APValueToBufferConverter {
5434 BitCastBuffer Buffer;
5437 APValueToBufferConverter(EvalInfo &Info,
CharUnits ObjectWidth,
5440 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
5449 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
5466 return visitArray(Val, Ty, Offset);
5468 return visitRecord(Val, Ty, Offset);
5480 diag::note_constexpr_bit_cast_unsupported_type)
5486 llvm_unreachable(
"LValue subobject in bit_cast?");
5488 llvm_unreachable(
"Unhandled APValue::ValueKind");
5496 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
5497 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
5508 unsigned FieldIdx = 0;
5510 if (FD->isBitField()) {
5512 diag::note_constexpr_bit_cast_unsupported_bitfield);
5518 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
5519 "only bit-fields can have sub-char alignment");
5521 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) +
Offset;
5537 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->getElementType());
5541 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
5543 if (!visit(SubObj, CAT->getElementType(), Offset + I * ElemWidth))
5550 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
5551 if (!visit(Filler, CAT->getElementType(), Offset + I * ElemWidth))
5560 CharUnits Width = Info.Ctx.getTypeSizeInChars(Ty);
5562 llvm::StoreIntToMemory(Val, &*Bytes.begin(), Width.
getQuantity());
5563 Buffer.writeObject(Offset, Bytes);
5568 APSInt AsInt(Val.bitcastToAPInt());
5569 return visitInt(AsInt, Ty, Offset);
5576 APValueToBufferConverter Converter(Info, DstSize, BCE);
5579 return Converter.Buffer;
5584 class BufferToAPValueConverter {
5586 const BitCastBuffer &Buffer;
5589 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
5591 : Info(Info), Buffer(Buffer), BCE(BCE) {}
5596 llvm::NoneType unsupportedType(
QualType Ty) {
5598 diag::note_constexpr_bit_cast_unsupported_type)
5604 const EnumType *EnumSugar =
nullptr) {
5606 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(
QualType(T, 0));
5612 CharUnits SizeOf = Info.Ctx.getTypeSizeInChars(T);
5614 if (!Buffer.readObject(Offset, SizeOf, Bytes)) {
5617 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
5621 if (!IsStdByte && !IsUChar) {
5622 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
5624 diag::note_constexpr_bit_cast_indet_dest)
5625 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
5632 APSInt Val(SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
5633 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
5641 const llvm::fltSemantics &Semantics =
5642 Info.Ctx.getFloatTypeSemantics(
QualType(T, 0));
5643 return APValue(APFloat(Semantics, Val));
5646 return unsupportedType(
QualType(T, 0));
5653 unsigned NumBases = 0;
5654 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
5655 NumBases = CXXRD->getNumBases();
5661 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
5662 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
5666 Info.Ctx.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero())
5678 unsigned FieldIdx = 0;
5682 if (FD->isBitField()) {
5684 diag::note_constexpr_bit_cast_unsupported_bitfield);
5689 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
5707 assert(!RepresentationType.
isNull() &&
5708 "enum forward decl should be caught by Sema");
5711 assert(AsBuiltin &&
"non-integral enum underlying type?");
5714 return visit(AsBuiltin, Offset, Ty);
5718 size_t Size = Ty->
getSize().getLimitedValue();
5722 for (
size_t I = 0; I != Size; ++I) {
5734 return unsupportedType(
QualType(Ty, 0));
5741 #define TYPE(Class, Base) \ 5743 return visit(cast<Class##Type>(Can.getTypePtr()), Offset); 5744 #define ABSTRACT_TYPE(Class, Base) 5745 #define NON_CANONICAL_TYPE(Class, Base) \ 5747 llvm_unreachable("non-canonical type should be impossible!"); 5748 #define DEPENDENT_TYPE(Class, Base) \ 5751 "dependent types aren't supported in the constant evaluator!"); 5752 #define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \ 5754 llvm_unreachable("either dependent or not canonical!"); 5755 #include "clang/AST/TypeNodes.def" 5757 llvm_unreachable(
"Unhandled Type::TypeClass");
5764 BufferToAPValueConverter Converter(Info, Buffer, BCE);
5769 static bool checkBitCastConstexprEligibilityType(
SourceLocation Loc,
5772 bool CheckingDest) {
5775 auto diag = [&](
int Reason) {
5777 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
5778 << CheckingDest << (Reason == 4) << Reason;
5783 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
5784 << NoteTy << Construct << Ty;
5798 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(Record)) {
5800 if (!checkBitCastConstexprEligibilityType(Loc, BS.getType(), Info, Ctx,
5802 return note(1, BS.getType(), BS.getBeginLoc());
5804 for (
FieldDecl *FD : Record->fields()) {
5805 if (FD->getType()->isReferenceType())
5807 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
5809 return note(0, FD->getType(), FD->getBeginLoc());
5815 Info, Ctx, CheckingDest))
5821 static bool checkBitCastConstexprEligibility(EvalInfo *Info,
5824 bool DestOK = checkBitCastConstexprEligibilityType(
5826 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
5832 static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
5835 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
5836 "no host or target supports non 8-bit chars");
5838 "LValueToRValueBitcast requires an lvalue operand!");
5840 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
5843 LValue SourceLValue;
5845 SourceLValue.setFrom(Info.Ctx, SourceValue);
5848 SourceLValue, SourceRValue))
5853 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
5859 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
5860 if (!MaybeDestValue)
5863 DestValue = std::move(*MaybeDestValue);
5867 template <
class Derived>
5868 class ExprEvaluatorBase
5871 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
5873 return getDerived().Success(V, E);
5875 bool DerivedZeroInitialization(
const Expr *E) {
5876 return getDerived().ZeroInitialization(E);
5882 template<
typename ConditionalOperator>
5884 assert(Info.checkingPotentialConstantExpression());
5889 SpeculativeEvaluationRAII Speculate(Info, &Diag);
5896 SpeculativeEvaluationRAII Speculate(Info, &Diag);
5903 Error(E, diag::note_constexpr_conditional_never_const);
5907 template<
typename ConditionalOperator>
5911 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
5912 CheckPotentialConstantConditional(E);
5915 if (Info.noteFailure()) {
5923 return StmtVisitorTy::Visit(EvalExpr);
5929 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
5932 return Info.CCEDiag(E, D);
5935 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
5938 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
5940 EvalInfo &getEvalInfo() {
return Info; }
5949 return Error(E, diag::note_invalid_subexpr_in_const_expr);
5952 bool VisitStmt(
const Stmt *) {
5953 llvm_unreachable(
"Expression evaluator should not be called on stmts");
5955 bool VisitExpr(
const Expr *E) {
5960 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
5962 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
5964 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
5966 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
5974 TempVersionRAII RAII(*Info.CurrentCall);
5975 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
5976 return StmtVisitorTy::Visit(E->
getExpr());
5979 TempVersionRAII RAII(*Info.CurrentCall);
5983 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
5984 return StmtVisitorTy::Visit(E->
getExpr());
5990 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
5993 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
5994 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
5997 if (!Info.Ctx.getLangOpts().CPlusPlus2a)
5998 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
5999 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
6002 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
6011 VisitIgnoredValue(E->
getLHS());
6012 return StmtVisitorTy::Visit(E->
getRHS());
6022 return DerivedSuccess(Result, E);
6034 return HandleConditionalOperator(E);
6038 bool IsBcpCall =
false;
6045 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
6050 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
6053 FoldConstant Fold(Info, IsBcpCall);
6054 if (!HandleConditionalOperator(E)) {
6055 Fold.keepDiagnostics();
6063 if (
APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
6064 return DerivedSuccess(*Value, E);
6070 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
6073 return StmtVisitorTy::Visit(Source);
6076 bool VisitCallExpr(
const CallExpr *E) {
6078 if (!handleCallExpr(E, Result,
nullptr))
6080 return DerivedSuccess(Result, E);
6084 const LValue *ResultSlot) {
6089 LValue *This =
nullptr, ThisVal;
6091 bool HasQualifier =
false;
6096 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
6102 return Error(Callee);
6104 HasQualifier = ME->hasQualifier();
6105 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
6107 Member = dyn_cast_or_null<CXXMethodDecl>(
6110 return Error(Callee);
6113 return Error(Callee);
6120 if (!Call.getLValueOffset().isZero())
6121 return Error(Callee);
6122 FD = dyn_cast_or_null<FunctionDecl>(
6123 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
6125 return Error(Callee);
6128 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
6146 Args = Args.slice(1);
6155 "Number of captures must be zero for conversion to function-ptr");
6166 "A generic lambda's static-invoker function must be a " 6167 "template specialization");
6170 LambdaCallOp->getDescribedFunctionTemplate();
6171 void *InsertPos =
nullptr;
6174 assert(CorrespondingCallOpSpecialization &&
6175 "We must always have a function call operator specialization " 6176 "that corresponds to our static invoker specialization");
6177 FD = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
6187 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
6190 CovariantAdjustmentPath);
6208 if (!CovariantAdjustmentPath.empty() &&
6210 CovariantAdjustmentPath))
6221 return DerivedZeroInitialization(E);
6223 return StmtVisitorTy::Visit(E->
getInit(0));
6227 return DerivedZeroInitialization(E);
6230 return DerivedZeroInitialization(E);
6233 return DerivedZeroInitialization(E);
6238 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
6239 "missing temporary materialization conversion");
6240 assert(!E->
isArrow() &&
"missing call to bound member function?");
6249 if (!FD)
return Error(E);
6259 Designator.addDeclUnchecked(FD);
6263 DerivedSuccess(Result, E);
6266 bool VisitCastExpr(
const CastExpr *E) {
6271 case CK_AtomicToNonAtomic: {
6278 return DerivedSuccess(AtomicVal, E);
6282 case CK_UserDefinedConversion:
6283 return StmtVisitorTy::Visit(E->
getSubExpr());
6285 case CK_LValueToRValue: {
6294 return DerivedSuccess(RVal, E);
6296 case CK_LValueToRValueBitCast: {
6297 APValue DestValue, SourceValue;
6300 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
6302 return DerivedSuccess(DestValue, E);
6310 return VisitUnaryPostIncDec(UO);
6313 return VisitUnaryPostIncDec(UO);
6316 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
6326 return DerivedSuccess(RVal, UO);
6329 bool VisitStmtExpr(
const StmtExpr *E) {
6332 if (Info.checkingForOverflow())
6335 BlockScopeRAII
Scope(Info);
6344 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
6346 Info.FFDiag((*BI)->getBeginLoc(),
6347 diag::note_constexpr_stmt_expr_unsupported);
6350 return this->Visit(FinalExpr);
6354 StmtResult Result = { ReturnValue,
nullptr };
6356 if (ESR != ESR_Succeeded) {
6360 if (ESR != ESR_Failed)
6361 Info.FFDiag((*BI)->getBeginLoc(),
6362 diag::note_constexpr_stmt_expr_unsupported);
6367 llvm_unreachable(
"Return from function from the loop above.");
6371 void VisitIgnoredValue(
const Expr *E) {
6376 void VisitIgnoredBaseExpression(
const Expr *E) {
6379 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
6381 VisitIgnoredValue(E);
6391 template<
class Derived>
6392 class LValueExprEvaluatorBase
6393 :
public ExprEvaluatorBase<Derived> {
6397 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
6398 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
6405 bool evaluatePointer(
const Expr *E, LValue &Result) {
6410 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
6411 : ExprEvaluatorBaseTy(Info),
Result(Result),
6412 InvalidBaseOK(InvalidBaseOK) {}
6415 Result.setFrom(this->Info.Ctx, V);
6431 EvalOK = this->Visit(E->
getBase());
6437 Result.setInvalid(E);
6444 FD->
getParent()->getCanonicalDecl() &&
"record / field mismatch");
6452 return this->
Error(E);
6459 return Success(RefValue, E);
6467 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
6475 bool VisitCastExpr(
const CastExpr *E) {
6478 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6480 case CK_DerivedToBase:
6481 case CK_UncheckedDerivedToBase:
6526 class LValueExprEvaluator
6527 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
6529 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
6530 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
6532 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
6536 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
6540 bool VisitStringLiteral(
const StringLiteral *E) {
return Success(E); }
6541 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
6549 return VisitUnaryPreIncDec(UO);
6552 return VisitUnaryPreIncDec(UO);
6557 bool VisitCastExpr(
const CastExpr *E) {
6560 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
6562 case CK_LValueBitCast:
6563 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
6566 Result.Designator.setInvalid();
6569 case CK_BaseToDerived:
6589 bool InvalidBaseOK) {
6592 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
6595 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
6599 return VisitVarDecl(E, VD);
6601 return Visit(BD->getBinding());
6606 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
6613 isa<DeclRefExpr>(E) &&
6614 cast<DeclRefExpr>(E)->refersToEnclosingVariableOrCapture()) {
6619 if (Info.checkingPotentialConstantExpression())
6622 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
6624 Result = *Info.CurrentCall->This;
6631 if (FD->getType()->isReferenceType()) {
6636 Result.setFrom(Info.Ctx, RVal);
6641 CallStackFrame *Frame =
nullptr;
6649 if (Info.CurrentCall->Callee &&
6651 Frame = Info.CurrentCall;
6657 Result.set({VD, Frame->Index,
6658 Info.CurrentCall->getCurrentTemporaryVersion(VD)});
6670 if (!Info.checkingPotentialConstantExpression())
6671 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
6674 return Success(*V, E);
6677 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
6683 skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
6686 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
6695 Value = Info.Ctx.getMaterializedTemporaryValue(E,
true);
6714 for (
unsigned I = Adjustments.size(); I != 0; ) {
6716 switch (Adjustments[I].
Kind) {
6721 Type = Adjustments[I].DerivedToBase.BasePath->getType();
6727 Type = Adjustments[I].Field->getType();
6732 Adjustments[I].Ptr.RHS))
6734 Type = Adjustments[I].Ptr.MPT->getPointeeType();
6744 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
6745 "lvalue compound literal in c++?");
6751 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
6760 if (!Info.Ctx.getLangOpts().CPlusPlus2a) {
6761 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
6775 TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
6781 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
6785 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
6788 VisitIgnoredBaseExpression(E->
getBase());
6789 return VisitVarDecl(E, VD);
6794 if (MD->isStatic()) {
6795 VisitIgnoredBaseExpression(E->
getBase());
6801 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
6809 bool Success =
true;
6811 if (!Info.noteFailure())
6824 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
6828 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
6837 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
6839 "lvalue __imag__ on scalar?");
6846 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
6847 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
6858 bool LValueExprEvaluator::VisitCompoundAssignOperator(
6860 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
6866 if (!this->Visit(CAO->
getLHS())) {
6867 if (Info.noteFailure())
6881 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
6882 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
6887 if (!this->Visit(E->
getLHS())) {
6888 if (Info.noteFailure())
6896 if (Info.getLangOpts().CPlusPlus2a &&
6916 llvm::APInt &Result) {
6917 const AllocSizeAttr *AllocSize = getAllocSizeAttr(Call);
6919 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
6920 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
6925 auto EvaluateAsSizeT = [&](
const Expr *E, APSInt &Into) {
6930 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
6932 Into = Into.zextOrSelf(BitsInSizeT);
6937 if (!EvaluateAsSizeT(Call->
getArg(SizeArgNo), SizeOfElem))
6940 if (!AllocSize->getNumElemsParam().isValid()) {
6941 Result = std::move(SizeOfElem);
6945 APSInt NumberOfElems;
6946 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
6947 if (!EvaluateAsSizeT(Call->
getArg(NumArgNo), NumberOfElems))
6951 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
6955 Result = std::move(BytesAvailable);
6963 llvm::APInt &Result) {
6964 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
6965 "Can't get the size of a non alloc_size function");
6966 const auto *Base = LVal.getLValueBase().get<
const Expr *>();
6967 const CallExpr *CE = tryUnwrapAllocSizeCall(Base);
6995 if (!tryUnwrapAllocSizeCall(E))
7000 Result.setInvalid(E);
7003 Result.addUnsizedArray(Info, E, Pointee);
7008 class PointerExprEvaluator
7009 :
public ExprEvaluatorBase<PointerExprEvaluator> {
7013 bool Success(
const Expr *E) {
7018 bool evaluateLValue(
const Expr *E, LValue &Result) {
7022 bool evaluatePointer(
const Expr *E, LValue &Result) {
7026 bool visitNonBuiltinCallExpr(
const CallExpr *E);
7029 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
7030 : ExprEvaluatorBaseTy(info),
Result(Result),
7031 InvalidBaseOK(InvalidBaseOK) {}
7034 Result.setFrom(Info.Ctx, V);
7037 bool ZeroInitialization(
const Expr *E) {
7038 auto TargetVal = Info.Ctx.getTargetNullPointerValue(E->
getType());
7039 Result.setNull(E->
getType(), TargetVal);
7044 bool VisitCastExpr(
const CastExpr* E);
7047 {
return Success(E); }
7051 if (Info.noteFailure())
7056 {
return Success(E); }
7057 bool VisitCallExpr(
const CallExpr *E);
7058 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
7059 bool VisitBlockExpr(
const BlockExpr *E) {
7066 if (Info.checkingPotentialConstantExpression())
7068 if (!Info.CurrentCall->This) {
7069 if (Info.getLangOpts().CPlusPlus11)
7070 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
7075 Result = *Info.CurrentCall->This;
7084 Info.CurrentCall->LambdaThisCaptureField))
7087 if (Info.CurrentCall->LambdaThisCaptureField->getType()
7088 ->isPointerType()) {
7094 Result.setFrom(Info.Ctx, RVal);
7101 assert(E->
isStringType() &&
"SourceLocExpr isn't a pointer type?");
7103 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
7104 Result.setFrom(Info.Ctx, LValResult);
7113 bool InvalidBaseOK) {
7115 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
7118 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
7121 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7126 std::swap(PExp, IExp);
7128 bool EvalPtrOK = evaluatePointer(PExp, Result);
7129 if (!EvalPtrOK && !Info.noteFailure())
7143 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
7147 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
7154 case CK_CPointerToObjCPointerCast:
7155 case CK_BlockPointerToObjCPointerCast:
7156 case CK_AnyPointerToBlockPointerCast:
7157 case CK_AddressSpaceConversion:
7158 if (!Visit(SubExpr))
7164 Result.Designator.setInvalid();
7166 CCEDiag(E, diag::note_constexpr_invalid_cast)
7169 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
7171 if (E->
getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
7172 ZeroInitialization(E);
7175 case CK_DerivedToBase:
7176 case CK_UncheckedDerivedToBase:
7179 if (!Result.Base && Result.Offset.isZero())
7185 castAs<PointerType>()->getPointeeType(),
7188 case CK_BaseToDerived:
7191 if (!Result.Base && Result.Offset.isZero())
7200 case CK_NullToPointer:
7202 return ZeroInitialization(E);
7204 case CK_IntegralToPointer: {
7205 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
7211 if (Value.
isInt()) {
7212 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
7213 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
7214 Result.Base = (
Expr*)
nullptr;
7215 Result.InvalidBase =
false;
7217 Result.Designator.setInvalid();
7218 Result.IsNullPtr =
false;
7222 Result.setFrom(Info.Ctx, Value);
7227 case CK_ArrayToPointerDecay: {
7229 if (!evaluateLValue(SubExpr, Result))
7238 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
7239 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
7240 Result.addArray(Info, E, CAT);
7246 case CK_FunctionToPointerDecay:
7247 return evaluateLValue(SubExpr, Result);
7249 case CK_LValueToRValue: {
7258 return InvalidBaseOK &&
7260 return Success(RVal, E);
7264 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7278 const bool AlignOfReturnsPreferred =
7285 return Info.Ctx.toCharUnitsFromBits(
7286 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
7289 return Info.Ctx.getTypeAlignInChars(T.
getTypePtr());
7291 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
7304 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
7305 return Info.Ctx.getDeclAlign(DRE->getDecl(),
7308 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
7309 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
7316 bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
7317 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
7320 if (!(InvalidBaseOK && getAllocSizeAttr(E)))
7323 Result.setInvalid(E);
7325 Result.addUnsizedArray(Info, E, PointeeTy);
7329 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
7334 return VisitBuiltinCallExpr(E, BuiltinOp);
7336 return visitNonBuiltinCallExpr(E);
7339 bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
7340 unsigned BuiltinOp) {
7341 switch (BuiltinOp) {
7342 case Builtin::BI__builtin_addressof:
7344 case Builtin::BI__builtin_assume_aligned: {
7351 LValue OffsetResult(Result);
7362 int64_t AdditionalOffset = -Offset.getZExtValue();
7367 if (OffsetResult.Base) {
7370 OffsetResult.Base.dyn_cast<
const ValueDecl*>()) {
7371 BaseAlignment = Info.Ctx.getDeclAlign(VD);
7372 }
else if (
const Expr *E = OffsetResult.Base.dyn_cast<
const Expr *>()) {
7376 Info, OffsetResult.Base.getTypeInfoType(),
UETT_AlignOf);
7379 if (BaseAlignment < Align) {
7380 Result.Designator.setInvalid();
7383 diag::note_constexpr_baa_insufficient_alignment) << 0
7391 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
7392 Result.Designator.setInvalid();
7396 diag::note_constexpr_baa_insufficient_alignment) << 1
7398 diag::note_constexpr_baa_value_insufficient_alignment))
7399 << (int)OffsetResult.Offset.getQuantity()
7406 case Builtin::BI__builtin_launder:
7408 case Builtin::BIstrchr:
7409 case Builtin::BIwcschr:
7410 case Builtin::BImemchr:
7411 case Builtin::BIwmemchr:
7412 if (Info.getLangOpts().CPlusPlus11)
7413 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
7415 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
7417 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
7419 case Builtin::BI__builtin_strchr:
7420 case Builtin::BI__builtin_wcschr:
7421 case Builtin::BI__builtin_memchr:
7422 case Builtin::BI__builtin_char_memchr:
7423 case Builtin::BI__builtin_wmemchr: {
7424 if (!Visit(E->
getArg(0)))
7429 uint64_t MaxLength = uint64_t(-1);
7430 if (BuiltinOp != Builtin::BIstrchr &&
7431 BuiltinOp != Builtin::BIwcschr &&
7432 BuiltinOp != Builtin::BI__builtin_strchr &&
7433 BuiltinOp != Builtin::BI__builtin_wcschr) {
7437 MaxLength = N.getExtValue();
7440 if (MaxLength == 0u)
7441 return ZeroInitialization(E);
7442 if (!Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
7443 Result.Designator.Invalid)
7445 QualType CharTy = Result.Designator.getType(Info.Ctx);
7446 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
7447 BuiltinOp == Builtin::BI__builtin_memchr;
7449 Info.Ctx.hasSameUnqualifiedType(
7453 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
7458 if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) !=
CharUnits::One())
7462 uint64_t DesiredVal;
7463 bool StopAtNull =
false;
7464 switch (BuiltinOp) {
7465 case Builtin::BIstrchr:
7466 case Builtin::BI__builtin_strchr:
7473 return ZeroInitialization(E);
7476 case Builtin::BImemchr:
7477 case Builtin::BI__builtin_memchr:
7478 case Builtin::BI__builtin_char_memchr:
7482 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
7485 case Builtin::BIwcschr:
7486 case Builtin::BI__builtin_wcschr:
7489 case Builtin::BIwmemchr:
7490 case Builtin::BI__builtin_wmemchr:
7492 DesiredVal = Desired.getZExtValue();
7496 for (; MaxLength; --MaxLength) {
7501 if (Char.
getInt().getZExtValue() == DesiredVal)
7503 if (StopAtNull && !Char.
getInt())
7509 return ZeroInitialization(E);
7512 case Builtin::BImemcpy:
7513 case Builtin::BImemmove:
7514 case Builtin::BIwmemcpy:
7515 case Builtin::BIwmemmove:
7516 if (Info.getLangOpts().CPlusPlus11)
7517 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
7519 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
7521 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
7523 case Builtin::BI__builtin_memcpy:
7524 case Builtin::BI__builtin_memmove:
7525 case Builtin::BI__builtin_wmemcpy:
7526 case Builtin::BI__builtin_wmemmove: {
7527 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
7528 BuiltinOp == Builtin::BIwmemmove ||
7529 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
7530 BuiltinOp == Builtin::BI__builtin_wmemmove;
7531 bool Move = BuiltinOp == Builtin::BImemmove ||
7532 BuiltinOp == Builtin::BIwmemmove ||
7533 BuiltinOp == Builtin::BI__builtin_memmove ||
7534 BuiltinOp == Builtin::BI__builtin_wmemmove;
7537 if (!Visit(E->
getArg(0)))
7548 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
7558 if (!Src.Base || !Dest.Base) {
7560 (!Src.Base ? Src : Dest).moveInto(Val);
7561 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
7562 << Move << WChar << !!Src.Base
7566 if (Src.Designator.Invalid || Dest.Designator.Invalid)
7572 QualType T = Dest.Designator.getType(Info.Ctx);
7573 QualType SrcT = Src.Designator.getType(Info.Ctx);
7574 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
7575 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << SrcT << T;
7579 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) << Move << T;
7583 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) << Move << T;
7588 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
7591 llvm::APInt OrigN = N;
7592 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
7594 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
7595 << Move << WChar << 0 << T << OrigN.toString(10,
false)
7604 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
7605 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
7606 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
7607 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
7608 << Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
7609 << N.toString(10,
false);
7612 uint64_t NElems = N.getZExtValue();
7613 uint64_t NBytes = NElems * TSize;
7618 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
7619 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
7620 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
7623 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
7631 }
else if (!Move && SrcOffset >= DestOffset &&
7632 SrcOffset - DestOffset < NBytes) {
7634 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
7655 return visitNonBuiltinCallExpr(E);
7664 class MemberPointerExprEvaluator
7665 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
7669 Result = MemberPtr(D);
7674 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
7675 : ExprEvaluatorBaseTy(Info),
Result(Result) {}
7681 bool ZeroInitialization(
const Expr *E) {
7682 return Success((
const ValueDecl*)
nullptr);
7685 bool VisitCastExpr(
const CastExpr *E);
7693 return MemberPointerExprEvaluator(Info, Result).Visit(E);
7696 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
7699 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7701 case CK_NullToMemberPointer:
7703 return ZeroInitialization(E);
7705 case CK_BaseToDerivedMemberPointer: {
7713 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
7715 PathI != PathE; ++PathI) {
7716 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
7717 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
7718 if (!Result.castToDerived(Derived))
7727 case CK_DerivedToBaseMemberPointer:
7731 PathE = E->
path_end(); PathI != PathE; ++PathI) {
7732 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
7733 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
7734 if (!Result.castToBase(Base))
7741 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
7744 return Success(cast<DeclRefExpr>(E->
getSubExpr())->getDecl());
7752 class RecordExprEvaluator
7753 :
public ExprEvaluatorBase<RecordExprEvaluator> {
7758 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
7759 : ExprEvaluatorBaseTy(info), This(This),
Result(Result) {}
7765 bool ZeroInitialization(
const Expr *E) {
7766 return ZeroInitialization(E, E->
getType());
7770 bool VisitCallExpr(
const CallExpr *E) {
7771 return handleCallExpr(E, Result, &This);
7773 bool VisitCastExpr(
const CastExpr *E);
7776 return VisitCXXConstructExpr(E, E->
getType());
7796 const LValue &This,
APValue &Result) {
7797 assert(!RD->
isUnion() &&
"Expected non-union class type");
7808 End = CD->bases_end(); I !=
End; ++I, ++Index) {
7809 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
7810 LValue Subobject = This;
7814 Result.getStructBase(Index)))
7819 for (
const auto *I : RD->
fields()) {
7821 if (I->getType()->isReferenceType())
7824 LValue Subobject = This;
7830 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
7837 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
7849 LValue Subobject = This;
7854 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
7857 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
7858 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
7865 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
7868 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7870 case CK_ConstructorConversion:
7873 case CK_DerivedToBase:
7874 case CK_UncheckedDerivedToBase: {
7882 APValue *Value = &DerivedObject;
7885 PathE = E->
path_end(); PathI != PathE; ++PathI) {
7886 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
7887 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
7897 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
7906 EvalInfo::EvaluatingConstructorRAII EvalObj(
7908 ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries},
7909 CXXRD && CXXRD->getNumBases());
7925 LValue Subobject = This;
7930 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
7931 isa<CXXDefaultInitExpr>(InitExpr));
7933 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
7936 if (!Result.hasValue())
7939 unsigned ElementNo = 0;
7940 bool Success =
true;
7943 if (CXXRD && CXXRD->getNumBases()) {
7944 for (
const auto &Base : CXXRD->bases()) {
7945 assert(ElementNo < E->getNumInits() &&
"missing init for base class");
7948 LValue Subobject = This;
7952 APValue &FieldVal = Result.getStructBase(ElementNo);
7954 if (!Info.noteFailure())
7961 EvalObj.finishedConstructingBases();
7965 for (
const auto *Field : RD->
fields()) {
7968 if (Field->isUnnamedBitfield())
7971 LValue Subobject = This;
7978 Subobject, Field, &Layout))
7984 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
7987 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
7988 isa<CXXDefaultInitExpr>(Init));
7990 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
7993 FieldVal, Field))) {
7994 if (!Info.noteFailure())
8013 if (Result.hasValue())
8024 return ZeroInitialization(E, T);
8028 auto Body = FD->
getBody(Definition);
8036 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
8037 return Visit(ME->GetTemporaryExpr());
8039 if (ZeroInit && !ZeroInitialization(E, T))
8044 cast<CXXConstructorDecl>(Definition), Info,
8048 bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
8050 if (!Info.CurrentCall) {
8051 assert(Info.checkingPotentialConstantExpression());
8060 auto Body = FD->
getBody(Definition);
8066 cast<CXXConstructorDecl>(Definition), Info,
8070 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
8080 Array.addArray(Info, E, ArrayType);
8089 if (!Field->getType()->isPointerType() ||
8090 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
8096 Array.moveInto(Result.getStructField(0));
8101 if (Field->getType()->isPointerType() &&
8102 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
8107 ArrayType->
getSize().getZExtValue()))
8109 Array.moveInto(Result.getStructField(1));
8110 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
8112 Result.getStructField(1) =
APValue(APSInt(ArrayType->
getSize()));
8122 bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
8126 if (Info.checkingPotentialConstantExpression())
return true;
8128 const size_t NumFields =
8133 "The number of lambda capture initializers should equal the number of " 8134 "fields within the closure type");
8141 bool Success =
true;
8142 for (
const auto *Field : ClosureClass->
fields()) {
8145 Expr *
const CurFieldInit = *CaptureInitIt++;
8152 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
8154 if (!Info.keepEvaluatingAfterFailure())
8164 APValue &Result, EvalInfo &Info) {
8166 "can't evaluate expression as a record rvalue");
8167 return RecordExprEvaluator(Info, This, Result).Visit(E);
8178 class TemporaryExprEvaluator
8179 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
8181 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
8182 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
8185 bool VisitConstructExpr(
const Expr *E) {
8190 bool VisitCastExpr(
const CastExpr *E) {
8193 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
8195 case CK_ConstructorConversion:
8200 return VisitConstructExpr(E);
8203 return VisitConstructExpr(E);
8205 bool VisitCallExpr(
const CallExpr *E) {
8206 return VisitConstructExpr(E);
8209 return VisitConstructExpr(E);
8212 return VisitConstructExpr(E);
8220 return TemporaryExprEvaluator(Info, Result).Visit(E);
8228 class VectorExprEvaluator
8229 :
public ExprEvaluatorBase<VectorExprEvaluator> {
8233 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
8234 : ExprEvaluatorBaseTy(info),
Result(Result) {}
8239 Result =
APValue(V.data(), V.size());
8247 bool ZeroInitialization(
const Expr *E);
8251 bool VisitCastExpr(
const CastExpr* E);
8262 return VectorExprEvaluator(Info, Result).Visit(E);
8265 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8273 case CK_VectorSplat: {
8279 Val =
APValue(std::move(IntResult));
8281 APFloat FloatResult(0.0);
8284 Val =
APValue(std::move(FloatResult));
8291 return Success(Elts, E);
8295 llvm::APInt SValInt;
8300 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
8301 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8304 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
8305 unsigned FloatEltSize = EltSize;
8306 if (&Sem == &APFloat::x87DoubleExtended())
8308 for (
unsigned i = 0;
i < NElts;
i++) {
8311 Elt = SValInt.rotl(
i*EltSize+FloatEltSize).trunc(FloatEltSize);
8313 Elt = SValInt.rotr(
i*EltSize).trunc(FloatEltSize);
8314 Elts.push_back(
APValue(APFloat(Sem, Elt)));
8317 for (
unsigned i = 0;
i < NElts;
i++) {
8320 Elt = SValInt.rotl(
i*EltSize+EltSize).zextOrTrunc(EltSize);
8322 Elt = SValInt.rotr(
i*EltSize).zextOrTrunc(EltSize);
8328 return Success(Elts, E);
8331 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8336 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
8348 unsigned CountInits = 0, CountElts = 0;
8349 while (CountElts < NumElements) {
8351 if (CountInits < NumInits
8357 for (
unsigned j = 0; j < vlen; j++)
8361 llvm::APSInt sInt(32);
8362 if (CountInits < NumInits) {
8366 sInt = Info.Ctx.MakeIntValue(0, EltTy);
8367 Elements.push_back(
APValue(sInt));
8370 llvm::APFloat f(0.0);
8371 if (CountInits < NumInits) {
8375 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
8376 Elements.push_back(
APValue(f));
8381 return Success(Elements, E);
8385 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
8389 if (EltTy->isIntegerType())
8390 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
8393 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
8396 return Success(Elements, E);
8399 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
8401 return ZeroInitialization(E);
8409 class ArrayExprEvaluator
8410 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
8415 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
8416 : ExprEvaluatorBaseTy(Info), This(This),
Result(Result) {}
8419 assert(V.
isArray() &&
"expected array");
8424 bool ZeroInitialization(
const Expr *E) {
8426 Info.Ctx.getAsConstantArrayType(E->
getType());
8431 CAT->
getSize().getZExtValue());
8435 LValue Subobject = This;
8436 Subobject.addArray(Info, E, CAT);
8441 bool VisitCallExpr(
const CallExpr *E) {
8442 return handleCallExpr(E, Result, &This);
8448 const LValue &Subobject,
8458 APValue &Result, EvalInfo &Info) {
8460 return ArrayExprEvaluator(Info, This, Result).Visit(E);
8467 if (isa<ImplicitValueInitExpr>(FillerExpr))
8469 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
8470 for (
unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) {
8479 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
8489 bool Success =
true;
8491 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
8492 "zero-initialized array shouldn't have any initialized elts");
8494 if (Result.isArray() && Result.hasArrayFiller())
8495 Filler = Result.getArrayFiller();
8498 unsigned NumElts = CAT->
getSize().getZExtValue();
8504 NumEltsToInit = NumElts;
8506 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: " 8507 << NumEltsToInit <<
".\n");
8514 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I)
8515 Result.getArrayInitializedElt(I) = Filler;
8516 if (Result.hasArrayFiller())
8517 Result.getArrayFiller() = Filler;
8520 LValue Subobject = This;
8521 Subobject.addArray(Info, E, CAT);
8522 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
8526 Info, Subobject, Init) ||
8529 if (!Info.noteFailure())
8535 if (!Result.hasArrayFiller())
8540 assert(FillerExpr &&
"no array filler for incomplete init list");
8542 FillerExpr) && Success;
8553 uint64_t Elements = CAT->getSize().getZExtValue();
8556 LValue Subobject = This;
8557 Subobject.addArray(Info, E, CAT);
8559 bool Success =
true;
8560 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
8564 CAT->getElementType(), 1)) {
8565 if (!Info.noteFailure())
8574 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
8575 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
8579 const LValue &Subobject,
8582 bool HadZeroInit = Value->
hasValue();
8585 unsigned N = CAT->getSize().getZExtValue();
8595 for (
unsigned I = 0; I != N; ++I)
8599 LValue ArrayElt = Subobject;
8600 ArrayElt.addArray(Info, E, CAT);
8601 for (
unsigned I = 0; I != N; ++I)
8603 CAT->getElementType()) ||
8605 CAT->getElementType(), 1))
8614 return RecordExprEvaluator(Info, Subobject, *Value)
8615 .VisitCXXConstructExpr(E, Type);
8627 class IntExprEvaluator
8628 :
public ExprEvaluatorBase<IntExprEvaluator> {
8632 : ExprEvaluatorBaseTy(info),
Result(result) {}
8634 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
8636 "Invalid evaluation result.");
8638 "Invalid evaluation result.");
8639 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
8640 "Invalid evaluation result.");
8644 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
8645 return Success(SI, E, Result);
8648 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
8650 "Invalid evaluation result.");
8651 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
8652 "Invalid evaluation result.");
8654 Result.
getInt().setIsUnsigned(
8658 bool Success(
const llvm::APInt &I,
const Expr *E) {
8659 return Success(I, E, Result);
8662 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
8664 "Invalid evaluation result.");
8668 bool Success(uint64_t Value,
const Expr *E) {
8669 return Success(Value, E, Result);
8681 return Success(V.
getInt(), E);
8684 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
8699 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
8701 if (CheckReferencedDecl(E, E->
getDecl()))
8704 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
8708 VisitIgnoredBaseExpression(E->
getBase());
8712 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
8715 bool VisitCallExpr(
const CallExpr *E);
8716 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
8721 bool VisitCastExpr(
const CastExpr* E);
8733 if (Info.ArrayInitIndex == uint64_t(-1)) {
8739 return Success(Info.ArrayInitIndex, E);
8744 return ZeroInitialization(E);
8768 class FixedPointExprEvaluator
8769 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
8774 : ExprEvaluatorBaseTy(info),
Result(result) {}
8776 bool Success(
const llvm::APInt &I,
const Expr *E) {
8781 bool Success(uint64_t Value,
const Expr *E) {
8793 "Invalid evaluation result.");
8806 bool VisitCastExpr(
const CastExpr *E);
8823 return IntExprEvaluator(Info, Result).Visit(E);
8833 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
8840 bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
8842 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.getDefaultExpr());
8843 return Success(Evaluated, E);
8850 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
8864 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
8879 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
8883 bool SameSign = (ECD->getInitVal().isSigned()
8885 bool SameWidth = (ECD->getInitVal().getBitWidth()
8886 == Info.Ctx.getIntWidth(E->
getType()));
8887 if (SameSign && SameWidth)
8888 return Success(ECD->getInitVal(), E);
8892 llvm::APSInt Val = ECD->getInitVal();
8894 Val.setIsSigned(!ECD->getInitVal().isSigned());
8896 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
8897 return Success(Val, E);
8942 switch (CanTy->getTypeClass()) {
8943 #define TYPE(ID, BASE) 8944 #define DEPENDENT_TYPE(ID, BASE) case Type::ID: 8945 #define NON_CANONICAL_TYPE(ID, BASE) case Type::ID: 8946 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID: 8947 #include "clang/AST/TypeNodes.def" 8949 case Type::DeducedTemplateSpecialization:
8950 llvm_unreachable(
"unexpected non-canonical or dependent type");
8954 #define BUILTIN_TYPE(ID, SINGLETON_ID) 8955 #define SIGNED_TYPE(ID, SINGLETON_ID) \ 8956 case BuiltinType::ID: return GCCTypeClass::Integer; 8957 #define FLOATING_TYPE(ID, SINGLETON_ID) \ 8958 case BuiltinType::ID: return GCCTypeClass::RealFloat; 8959 #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \ 8960 case BuiltinType::ID: break; 8961 #include "clang/AST/BuiltinTypes.def" 8962 case BuiltinType::Void:
8965 case BuiltinType::Bool:
8968 case BuiltinType::Char_U:
8969 case BuiltinType::UChar:
8970 case BuiltinType::WChar_U:
8971 case BuiltinType::Char8:
8972 case BuiltinType::Char16:
8973 case BuiltinType::Char32:
8974 case BuiltinType::UShort:
8975 case BuiltinType::UInt:
8976 case BuiltinType::ULong:
8977 case BuiltinType::ULongLong:
8978 case BuiltinType::UInt128:
8981 case BuiltinType::UShortAccum:
8982 case BuiltinType::UAccum:
8983 case BuiltinType::ULongAccum:
8984 case BuiltinType::UShortFract:
8985 case BuiltinType::UFract:
8986 case BuiltinType::ULongFract:
8987 case BuiltinType::SatUShortAccum:
8988 case BuiltinType::SatUAccum:
8989 case BuiltinType::SatULongAccum:
8990 case BuiltinType::SatUShortFract:
8991 case BuiltinType::SatUFract:
8992 case BuiltinType::SatULongFract:
8995 case BuiltinType::NullPtr:
8997 case BuiltinType::ObjCId:
8998 case BuiltinType::ObjCClass:
8999 case BuiltinType::ObjCSel:
9000 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 9001 case BuiltinType::Id: 9002 #include "clang/Basic/OpenCLImageTypes.def" 9003 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 9004 case BuiltinType::Id: 9005 #include "clang/Basic/OpenCLExtensionTypes.def" 9006 case BuiltinType::OCLSampler:
9007 case BuiltinType::OCLEvent:
9008 case BuiltinType::OCLClkEvent:
9009 case BuiltinType::OCLQueue:
9010 case BuiltinType::OCLReserveID:
9013 case BuiltinType::Dependent:
9014 llvm_unreachable(
"unexpected dependent type");
9016 llvm_unreachable(
"unexpected placeholder type");
9022 case Type::ConstantArray:
9023 case Type::VariableArray:
9024 case Type::IncompleteArray:
9025 case Type::FunctionNoProto:
9026 case Type::FunctionProto:
9029 case Type::MemberPointer:
9030 return CanTy->isMemberDataPointerType()
9046 case Type::BlockPointer:
9048 case Type::ExtVector:
9049 case Type::ObjCObject:
9050 case Type::ObjCInterface:
9051 case Type::ObjCObjectPointer:
9057 case Type::LValueReference:
9058 case Type::RValueReference:
9059 llvm_unreachable(
"invalid type for expression");
9062 llvm_unreachable(
"unexpected type class");
9091 if (!isa<StringLiteral>(E))
9109 SpeculativeEvaluationRAII SpeculativeEval(Info);
9114 FoldConstant Fold(Info,
true);
9137 Fold.keepDiagnostics();
9157 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9159 }
else if (
const Expr *E = B.
get<
const Expr*>()) {
9160 if (isa<CompoundLiteralExpr>(E))
9179 auto *Cast = dyn_cast<
CastExpr>(NoParens);
9180 if (Cast ==
nullptr)
9187 CastKind != CK_AddressSpaceConversion)
9190 auto *SubExpr = Cast->getSubExpr();
9191 if (!SubExpr->getType()->hasPointerRepresentation() || !SubExpr->isRValue())
9212 assert(!LVal.Designator.Invalid);
9214 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &Invalid) {
9217 if (Invalid || Parent->
isUnion())
9223 auto &Base = LVal.getLValueBase();
9224 if (
auto *ME = dyn_cast_or_null<MemberExpr>(Base.
dyn_cast<
const Expr *>())) {
9225 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
9227 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
9229 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
9230 for (
auto *FD : IFD->chain()) {
9232 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid))
9240 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
9250 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
9251 const auto &Entry = LVal.Designator.Entries[I];
9257 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
9258 uint64_t Index = Entry.getAsArrayIndex();
9259 if (Index + 1 != CAT->getSize())
9261 BaseType = CAT->getElementType();
9264 uint64_t Index = Entry.getAsArrayIndex();
9268 }
else if (
auto *FD = getAsField(Entry)) {
9270 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
9274 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
9286 if (LVal.Designator.Invalid)
9289 if (!LVal.Designator.Entries.empty())
9290 return LVal.Designator.isMostDerivedAnUnsizedArray();
9292 if (!LVal.InvalidBase)
9297 const auto *E = LVal.Base.dyn_cast<
const Expr *>();
9298 return !E || !isa<MemberExpr>(E);
9304 const SubobjectDesignator &
Designator = LVal.Designator;
9316 return LVal.InvalidBase &&
9317 Designator.Entries.size() == Designator.MostDerivedPathLength &&
9318 Designator.MostDerivedIsArrayElement &&
9327 if (Int.ugt(CharUnitsMax))
9340 unsigned Type,
const LValue &LVal,
9353 if (!(Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
9355 if (Type == 3 && !DetermineForCompleteObject)
9358 llvm::APInt APEndOffset;
9359 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9363 if (LVal.InvalidBase)
9367 return CheckedHandleSizeof(BaseTy, EndOffset);
9371 const SubobjectDesignator &
Designator = LVal.Designator;
9383 llvm::APInt APEndOffset;
9384 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9396 if (!CheckedHandleSizeof(Designator.MostDerivedType, BytesPerElem))
9402 int64_t ElemsRemaining;
9403 if (Designator.MostDerivedIsArrayElement &&
9404 Designator.Entries.size() == Designator.MostDerivedPathLength) {
9405 uint64_t ArraySize = Designator.getMostDerivedArraySize();
9406 uint64_t ArrayIndex = Designator.Entries.back().getAsArrayIndex();
9407 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
9409 ElemsRemaining = Designator.isOnePastTheEnd() ? 0 : 1;
9412 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
9422 EvalInfo &Info, uint64_t &Size) {
9429 SpeculativeEvaluationRAII SpeculativeEval(Info);
9430 IgnoreSideEffectsRAII Fold(Info);
9438 LVal.setFrom(Info.Ctx, RVal);
9446 if (LVal.getLValueOffset().isNegative()) {
9457 if (EndOffset <= LVal.getLValueOffset())
9460 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
9464 bool IntExprEvaluator::VisitConstantExpr(
const ConstantExpr *E) {
9468 return ExprEvaluatorBaseTy::VisitConstantExpr(E);
9471 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9473 return VisitBuiltinCallExpr(E, BuiltinOp);
9475 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9478 bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
9479 unsigned BuiltinOp) {
9482 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9484 case Builtin::BI__builtin_dynamic_object_size:
9485 case Builtin::BI__builtin_object_size: {
9489 assert(Type <= 3 &&
"unexpected type");
9493 return Success(Size, E);
9496 return Success((Type & 2) ? 0 : -1, E);
9500 switch (Info.EvalMode) {
9501 case EvalInfo::EM_ConstantExpression:
9502 case EvalInfo::EM_PotentialConstantExpression:
9503 case EvalInfo::EM_ConstantFold:
9504 case EvalInfo::EM_EvaluateForOverflow:
9505 case EvalInfo::EM_IgnoreSideEffects:
9508 case EvalInfo::EM_ConstantExpressionUnevaluated:
9509 case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
9511 return Success((Type & 2) ? 0 : -1, E);
9514 llvm_unreachable(
"unexpected EvalMode");
9517 case Builtin::BI__builtin_os_log_format_buffer_size: {
9523 case Builtin::BI__builtin_bswap16:
9524 case Builtin::BI__builtin_bswap32:
9525 case Builtin::BI__builtin_bswap64: {
9530 return Success(Val.byteSwap(), E);
9533 case Builtin::BI__builtin_classify_type:
9536 case Builtin::BI__builtin_clrsb:
9537 case Builtin::BI__builtin_clrsbl:
9538 case Builtin::BI__builtin_clrsbll: {
9543 return Success(Val.getBitWidth() - Val.getMinSignedBits(), E);
9546 case Builtin::BI__builtin_clz:
9547 case Builtin::BI__builtin_clzl:
9548 case Builtin::BI__builtin_clzll:
9549 case Builtin::BI__builtin_clzs: {
9556 return Success(Val.countLeadingZeros(), E);
9559 case Builtin::BI__builtin_constant_p: {
9562 return Success(
true, E);
9567 return Success(
false, E);
9569 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
9573 case Builtin::BI__builtin_is_constant_evaluated:
9574 return Success(Info.InConstantContext, E);
9576 case Builtin::BI__builtin_ctz:
9577 case Builtin::BI__builtin_ctzl:
9578 case Builtin::BI__builtin_ctzll:
9579 case Builtin::BI__builtin_ctzs: {
9586 return Success(Val.countTrailingZeros(), E);
9589 case Builtin::BI__builtin_eh_return_data_regno: {
9591 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
9592 return Success(Operand, E);
9595 case Builtin::BI__builtin_expect:
9596 return Visit(E->
getArg(0));
9598 case Builtin::BI__builtin_ffs:
9599 case Builtin::BI__builtin_ffsl:
9600 case Builtin::BI__builtin_ffsll: {
9605 unsigned N = Val.countTrailingZeros();
9606 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
9609 case Builtin::BI__builtin_fpclassify: {
9614 switch (Val.getCategory()) {
9615 case APFloat::fcNaN: Arg = 0;
break;
9616 case APFloat::fcInfinity: Arg = 1;
break;
9617 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
9618 case APFloat::fcZero: Arg = 4;
break;
9620 return Visit(E->
getArg(Arg));
9623 case Builtin::BI__builtin_isinf_sign: {
9626 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
9629 case Builtin::BI__builtin_isinf: {
9632 Success(Val.isInfinity() ? 1 : 0, E);
9635 case Builtin::BI__builtin_isfinite: {
9638 Success(Val.isFinite() ? 1 : 0, E);
9641 case Builtin::BI__builtin_isnan: {
9644 Success(Val.isNaN() ? 1 : 0, E);
9647 case Builtin::BI__builtin_isnormal: {
9650 Success(Val.isNormal() ? 1 : 0, E);
9653 case Builtin::BI__builtin_parity:
9654 case Builtin::BI__builtin_parityl:
9655 case Builtin::BI__builtin_parityll: {
9660 return Success(Val.countPopulation() % 2, E);
9663 case Builtin::BI__builtin_popcount:
9664 case Builtin::BI__builtin_popcountl:
9665 case Builtin::BI__builtin_popcountll: {
9670 return Success(Val.countPopulation(), E);
9673 case Builtin::BIstrlen:
9674 case Builtin::BIwcslen:
9676 if (Info.getLangOpts().CPlusPlus11)
9677 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9679 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
9681 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
9683 case Builtin::BI__builtin_strlen:
9684 case Builtin::BI__builtin_wcslen: {
9694 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
9695 String.getLValueBase().dyn_cast<
const Expr *>())) {
9698 StringRef Str = S->getBytes();
9699 int64_t Off = String.Offset.getQuantity();
9700 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
9701 S->getCharByteWidth() == 1 &&
9703 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
9704 Str = Str.substr(Off);
9706 StringRef::size_type Pos = Str.find(0);
9707 if (Pos != StringRef::npos)
9708 Str = Str.substr(0, Pos);
9710 return Success(Str.size(), E);
9717 for (uint64_t Strlen = 0; ; ++Strlen) {
9723 return Success(Strlen, E);
9729 case Builtin::BIstrcmp:
9730 case Builtin::BIwcscmp:
9731 case Builtin::BIstrncmp:
9732 case Builtin::BIwcsncmp:
9733 case Builtin::BImemcmp:
9734 case Builtin::BIbcmp:
9735 case Builtin::BIwmemcmp:
9737 if (Info.getLangOpts().CPlusPlus11)
9738 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9740 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
9742 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
9744 case Builtin::BI__builtin_strcmp:
9745 case Builtin::BI__builtin_wcscmp:
9746 case Builtin::BI__builtin_strncmp:
9747 case Builtin::BI__builtin_wcsncmp:
9748 case Builtin::BI__builtin_memcmp:
9749 case Builtin::BI__builtin_bcmp:
9750 case Builtin::BI__builtin_wmemcmp: {
9751 LValue String1, String2;
9756 uint64_t MaxLength = uint64_t(-1);
9757 if (BuiltinOp != Builtin::BIstrcmp &&
9758 BuiltinOp != Builtin::BIwcscmp &&
9759 BuiltinOp != Builtin::BI__builtin_strcmp &&
9760 BuiltinOp != Builtin::BI__builtin_wcscmp) {
9764 MaxLength = N.getExtValue();
9768 if (MaxLength == 0u)
9769 return Success(0, E);
9771 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
9772 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
9773 String1.Designator.Invalid || String2.Designator.Invalid)
9776 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
9777 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
9779 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
9780 BuiltinOp == Builtin::BIbcmp ||
9781 BuiltinOp == Builtin::BI__builtin_memcmp ||
9782 BuiltinOp == Builtin::BI__builtin_bcmp;
9785 (Info.Ctx.hasSameUnqualifiedType(
9787 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
9792 Char1.
isInt() && Char2.isInt();
9794 const auto &AdvanceElems = [&] {
9800 uint64_t BytesRemaining = MaxLength;
9803 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy1;
9807 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy2;
9810 uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)};
9811 CharUnits CharTy1Size = Info.Ctx.toCharUnitsFromBits(CharTy1Width);
9813 if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2))
9815 uint64_t BytesPerElement = CharTy1Size.
getQuantity();
9816 assert(BytesRemaining &&
"BytesRemaining should not be zero: the " 9817 "following loop considers at least one element");
9820 if (!ReadCurElems(Char1, Char2))
9827 APSInt Char1InMem = Char1.
getInt().extOrTrunc(CharTy1Width);
9828 APSInt Char2InMem = Char2.
getInt().extOrTrunc(CharTy1Width);
9829 if (Char1InMem.ne(Char2InMem)) {
9832 if (BytesPerElement == 1u) {
9834 return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E);
9840 if (!AdvanceElems())
9842 if (BytesRemaining <= BytesPerElement)
9844 BytesRemaining -= BytesPerElement;
9847 return Success(0, E);
9851 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
9852 BuiltinOp != Builtin::BIwmemcmp &&
9853 BuiltinOp != Builtin::BI__builtin_memcmp &&
9854 BuiltinOp != Builtin::BI__builtin_bcmp &&
9855 BuiltinOp != Builtin::BI__builtin_wmemcmp);
9856 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
9857 BuiltinOp == Builtin::BIwcsncmp ||
9858 BuiltinOp == Builtin::BIwmemcmp ||
9859 BuiltinOp == Builtin::BI__builtin_wcscmp ||
9860 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
9861 BuiltinOp == Builtin::BI__builtin_wmemcmp;
9863 for (; MaxLength; --MaxLength) {
9865 if (!ReadCurElems(Char1, Char2))
9869 return Success(Char1.
getInt() < Char2.
getInt() ? -1 : 1, E);
9871 return Success(Char1.
getInt().ult(Char2.
getInt()) ? -1 : 1, E);
9873 if (StopAtNull && !Char1.
getInt())
9874 return Success(0, E);
9875 assert(!(StopAtNull && !Char2.
getInt()));
9876 if (!AdvanceElems())
9880 return Success(0, E);
9883 case Builtin::BI__atomic_always_lock_free:
9884 case Builtin::BI__atomic_is_lock_free:
9885 case Builtin::BI__c11_atomic_is_lock_free: {
9903 unsigned InlineWidthBits =
9904 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
9905 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
9906 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
9912 return Success(1, E);
9915 castAs<PointerType>()->getPointeeType();
9917 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
9919 return Success(1, E);
9924 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
9925 Success(0, E) :
Error(E);
9927 case Builtin::BIomp_is_initial_device:
9929 return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E);
9930 case Builtin::BI__builtin_add_overflow:
9931 case Builtin::BI__builtin_sub_overflow:
9932 case Builtin::BI__builtin_mul_overflow:
9933 case Builtin::BI__builtin_sadd_overflow:
9934 case Builtin::BI__builtin_uadd_overflow:
9935 case Builtin::BI__builtin_uaddl_overflow:
9936 case Builtin::BI__builtin_uaddll_overflow:
9937 case Builtin::BI__builtin_usub_overflow:
9938 case Builtin::BI__builtin_usubl_overflow:
9939 case Builtin::BI__builtin_usubll_overflow:
9940 case Builtin::BI__builtin_umul_overflow:
9941 case Builtin::BI__builtin_umull_overflow:
9942 case Builtin::BI__builtin_umulll_overflow:
9943 case Builtin::BI__builtin_saddl_overflow:
9944 case Builtin::BI__builtin_saddll_overflow:
9945 case Builtin::BI__builtin_ssub_overflow:
9946 case Builtin::BI__builtin_ssubl_overflow:
9947 case Builtin::BI__builtin_ssubll_overflow:
9948 case Builtin::BI__builtin_smul_overflow:
9949 case Builtin::BI__builtin_smull_overflow:
9950 case Builtin::BI__builtin_smulll_overflow: {
9951 LValue ResultLValue;
9961 bool DidOverflow =
false;
9964 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
9965 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
9966 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
9967 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
9969 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
9971 uint64_t LHSSize = LHS.getBitWidth();
9972 uint64_t RHSSize = RHS.getBitWidth();
9973 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
9980 if (IsSigned && !AllSigned)
9983 LHS = APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
9984 RHS = APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
9985 Result = APSInt(MaxBits, !IsSigned);
9989 switch (BuiltinOp) {
9991 llvm_unreachable(
"Invalid value for BuiltinOp");
9992 case Builtin::BI__builtin_add_overflow:
9993 case Builtin::BI__builtin_sadd_overflow:
9994 case Builtin::BI__builtin_saddl_overflow:
9995 case Builtin::BI__builtin_saddll_overflow:
9996 case Builtin::BI__builtin_uadd_overflow:
9997 case Builtin::BI__builtin_uaddl_overflow:
9998 case Builtin::BI__builtin_uaddll_overflow:
9999 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
10000 : LHS.uadd_ov(RHS, DidOverflow);
10002 case Builtin::BI__builtin_sub_overflow:
10003 case Builtin::BI__builtin_ssub_overflow:
10004 case Builtin::BI__builtin_ssubl_overflow:
10005 case Builtin::BI__builtin_ssubll_overflow:
10006 case Builtin::BI__builtin_usub_overflow:
10007 case Builtin::BI__builtin_usubl_overflow:
10008 case Builtin::BI__builtin_usubll_overflow:
10009 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
10010 : LHS.usub_ov(RHS, DidOverflow);
10012 case Builtin::BI__builtin_mul_overflow:
10013 case Builtin::BI__builtin_smul_overflow:
10014 case Builtin::BI__builtin_smull_overflow:
10015 case Builtin::BI__builtin_smulll_overflow:
10016 case Builtin::BI__builtin_umul_overflow:
10017 case Builtin::BI__builtin_umull_overflow:
10018 case Builtin::BI__builtin_umulll_overflow:
10019 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
10020 : LHS.umul_ov(RHS, DidOverflow);
10026 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
10027 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
10028 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
10034 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
10037 if (!APSInt::isSameValue(Temp, Result))
10038 DidOverflow =
true;
10045 return Success(DidOverflow, E);
10053 const LValue &LV) {
10056 if (!LV.getLValueBase())
10061 if (!LV.getLValueDesignator().Invalid &&
10062 !LV.getLValueDesignator().isOnePastTheEnd())
10067 QualType Ty = getType(LV.getLValueBase());
10074 return LV.getLValueOffset() == Size;
10084 class DataRecursiveIntBinOpEvaluator {
10085 struct EvalResult {
10089 EvalResult() : Failed(
false) { }
10091 void swap(EvalResult &RHS) {
10093 Failed = RHS.Failed;
10094 RHS.Failed =
false;
10100 EvalResult LHSResult;
10101 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
10104 Job(Job &&) =
default;
10106 void startSpeculativeEval(EvalInfo &Info) {
10107 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
10111 SpeculativeEvaluationRAII SpecEvalRAII;
10116 IntExprEvaluator &IntEval;
10121 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
10122 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
10137 EvalResult PrevResult;
10138 while (!Queue.empty())
10139 process(PrevResult);
10141 if (PrevResult.Failed)
return false;
10143 FinalResult.
swap(PrevResult.Val);
10148 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
10149 return IntEval.Success(Value, E, Result);
10151 bool Success(
const APSInt &Value,
const Expr *E,
APValue &Result) {
10152 return IntEval.Success(Value, E, Result);
10155 return IntEval.Error(E);
10158 return IntEval.Error(E, D);
10162 return Info.CCEDiag(E, D);
10166 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
10167 bool &SuppressRHSDiags);
10169 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
10172 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
10173 Result.Failed = !
Evaluate(Result.Val, Info, E);
10178 void process(EvalResult &Result);
10180 void enqueue(
const Expr *E) {
10182 Queue.resize(Queue.size()+1);
10183 Queue.back().E = E;
10184 Queue.back().Kind = Job::AnyExprKind;
10190 bool DataRecursiveIntBinOpEvaluator::
10191 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
10192 bool &SuppressRHSDiags) {
10195 if (LHSResult.Failed)
10196 return Info.noteSideEffect();
10205 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
10206 Success(LHSAsBool, E, LHSResult.Val);
10210 LHSResult.Failed =
true;
10214 if (!Info.noteSideEffect())
10220 SuppressRHSDiags =
true;
10229 if (LHSResult.Failed && !Info.noteFailure())
10240 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
10243 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
10245 : Offset64 + Index64);
10248 bool DataRecursiveIntBinOpEvaluator::
10249 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
10252 if (RHSResult.Failed)
10254 Result = RHSResult.Val;
10259 bool lhsResult, rhsResult;
10266 return Success(lhsResult || rhsResult, E, Result);
10268 return Success(lhsResult && rhsResult, E, Result);
10274 if (rhsResult == (E->
getOpcode() == BO_LOr))
10275 return Success(rhsResult, E, Result);
10285 if (LHSResult.Failed || RHSResult.Failed)
10288 const APValue &LHSVal = LHSResult.Val;
10289 const APValue &RHSVal = RHSResult.Val;
10313 if (!LHSExpr || !RHSExpr)
10317 if (!LHSAddrExpr || !RHSAddrExpr)
10321 RHSAddrExpr->getLabel()->getDeclContext())
10323 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
10339 return Success(Value, E, Result);
10342 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
10343 Job &job = Queue.back();
10345 switch (job.Kind) {
10346 case Job::AnyExprKind: {
10347 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
10348 if (shouldEnqueue(Bop)) {
10349 job.Kind = Job::BinOpKind;
10350 enqueue(Bop->getLHS());
10355 EvaluateExpr(job.E, Result);
10360 case Job::BinOpKind: {
10362 bool SuppressRHSDiags =
false;
10363 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
10367 if (SuppressRHSDiags)
10368 job.startSpeculativeEval(Info);
10369 job.LHSResult.swap(Result);
10370 job.Kind = Job::BinOpVisitedLHSKind;
10375 case Job::BinOpVisitedLHSKind: {
10379 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
10385 llvm_unreachable(
"Invalid Job::Kind!");
10391 class DelayedNoteFailureRAII {
10396 DelayedNoteFailureRAII(EvalInfo &Info,
bool NoteFailure =
true)
10397 : Info(Info), NoteFailure(NoteFailure) {}
10398 ~DelayedNoteFailureRAII() {
10400 bool ContinueAfterFailure = Info.noteFailure();
10401 (void)ContinueAfterFailure;
10402 assert(ContinueAfterFailure &&
10403 "Shouldn't have kept evaluating on failure.");
10409 template <
class SuccessCB,
class AfterCB>
10412 SuccessCB &&Success, AfterCB &&DoAfter) {
10416 "unsupported binary expression evaluation");
10418 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
10427 Info.Ctx.CompCategories.getInfoForType(E->
getType());
10439 if (!LHSOK && !Info.noteFailure())
10451 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
10452 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
10455 if (!LHSOK && !Info.noteFailure())
10467 ComplexValue LHS, RHS;
10476 LHS.makeComplexFloat();
10477 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
10482 if (!LHSOK && !Info.noteFailure())
10488 RHS.makeComplexFloat();
10489 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
10493 if (LHS.isComplexFloat()) {
10494 APFloat::cmpResult CR_r =
10495 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
10496 APFloat::cmpResult CR_i =
10497 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
10498 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
10501 assert(IsEquality &&
"invalid complex comparison");
10502 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
10503 LHS.getComplexIntImag() == RHS.getComplexIntImag();
10510 APFloat RHS(0.0), LHS(0.0);
10513 if (!LHSOK && !Info.noteFailure())
10520 auto GetCmpRes = [&]() {
10521 switch (LHS.compare(RHS)) {
10522 case APFloat::cmpEqual:
10524 case APFloat::cmpLessThan:
10526 case APFloat::cmpGreaterThan:
10528 case APFloat::cmpUnordered:
10531 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
10533 return Success(GetCmpRes(), E);
10537 LValue LHSValue, RHSValue;
10540 if (!LHSOK && !Info.noteFailure())
10556 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
10557 (!RHSValue.Base && !RHSValue.Offset.isZero()))
10564 LHSValue.Base && RHSValue.Base)
10572 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
10574 (RHSValue.Base && RHSValue.Offset.isZero() &&
10585 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
10586 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
10588 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
10589 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
10599 Info.CCEDiag(E, diag::note_constexpr_void_comparison);
10609 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
10610 bool WasArrayIndex;
10612 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
10619 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
10620 Mismatch < RHSDesignator.Entries.size()) {
10621 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
10622 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
10624 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
10626 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
10627 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
10630 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
10631 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
10636 diag::note_constexpr_pointer_comparison_differing_access)
10644 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
10647 assert(PtrSize <= 64 &&
"Unexpected pointer width");
10648 uint64_t Mask = ~0ULL >> (64 - PtrSize);
10649 CompareLHS &= Mask;
10650 CompareRHS &= Mask;
10655 if (!LHSValue.Base.isNull() && IsRelational) {
10656 QualType BaseTy = getType(LHSValue.Base);
10659 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
10661 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
10665 if (CompareLHS < CompareRHS)
10667 if (CompareLHS > CompareRHS)
10673 assert(IsEquality &&
"unexpected member pointer operation");
10676 MemberPtr LHSValue, RHSValue;
10679 if (!LHSOK && !Info.noteFailure())
10688 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
10689 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
10695 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
10696 if (MD->isVirtual())
10697 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
10698 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
10699 if (MD->isVirtual())
10700 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
10706 bool Equal = LHSValue == RHSValue;
10712 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
10722 bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
10731 Info.Ctx.CompCategories.getInfoForType(E->
getType());
10742 return ExprEvaluatorBaseTy::VisitBinCmp(E);
10746 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10752 DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->
isAssignmentOp());
10753 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
10754 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
10758 "DataRecursiveIntBinOpEvaluator should have handled integral types");
10772 llvm_unreachable(
"unsupported binary operator");
10775 return Success(IsEqual == (Op == BO_EQ), E);
10776 case BO_LT:
return Success(IsLess, E);
10777 case BO_GT:
return Success(IsGreater, E);
10778 case BO_LE:
return Success(IsEqual || IsLess, E);
10779 case BO_GE:
return Success(IsEqual || IsGreater, E);
10783 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10792 LValue LHSValue, RHSValue;
10795 if (!LHSOK && !Info.noteFailure())
10805 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
10807 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
10808 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
10809 if (!LHSExpr || !RHSExpr)
10813 if (!LHSAddrExpr || !RHSAddrExpr)
10817 RHSAddrExpr->getLabel()->getDeclContext())
10819 return Success(
APValue(LHSAddrExpr, RHSAddrExpr), E);
10821 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
10822 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
10824 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
10825 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
10831 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
10834 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
10846 if (ElementSize.
isZero()) {
10847 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
10860 APSInt LHS(llvm::APInt(65, (int64_t)LHSOffset.
getQuantity(),
true),
false);
10861 APSInt RHS(llvm::APInt(65, (int64_t)RHSOffset.
getQuantity(),
true),
false);
10862 APSInt ElemSize(llvm::APInt(65, (int64_t)ElementSize.
getQuantity(),
true),
10864 APSInt TrueResult = (LHS - RHS) / ElemSize;
10865 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
10867 if (Result.extend(65) != TrueResult &&
10870 return Success(Result, E);
10873 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10878 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
10902 return Success(n, E);
10904 return Success(1, E);
10917 return Success(Sizeof, E);
10922 Info.Ctx.toCharUnitsFromBits(
10928 llvm_unreachable(
"unknown expr/type trait");
10931 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
10937 for (
unsigned i = 0;
i != n; ++
i) {
10945 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
10949 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
10950 Result += IdxResult.getSExtValue() * ElementSize;
10963 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
10970 llvm_unreachable(
"dependent __builtin_offsetof");
10986 CurrentType = BaseSpec->
getType();
10997 return Success(Result, OOE);
11000 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11016 if (!Result.isInt())
return Error(E);
11017 const APSInt &Value = Result.getInt();
11018 if (Value.isSigned() && Value.isMinSignedValue() && E->
canOverflow() &&
11019 !
HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),
11022 return Success(-Value, E);
11027 if (!Result.isInt())
return Error(E);
11028 return Success(~Result.getInt(), E);
11034 return Success(!bres, E);
11041 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11047 case CK_BaseToDerived:
11048 case CK_DerivedToBase:
11049 case CK_UncheckedDerivedToBase:
11052 case CK_ArrayToPointerDecay:
11053 case CK_FunctionToPointerDecay:
11054 case CK_NullToPointer:
11055 case CK_NullToMemberPointer:
11056 case CK_BaseToDerivedMemberPointer:
11057 case CK_DerivedToBaseMemberPointer:
11058 case CK_ReinterpretMemberPointer:
11059 case CK_ConstructorConversion:
11060 case CK_IntegralToPointer:
11062 case CK_VectorSplat:
11063 case CK_IntegralToFloating:
11064 case CK_FloatingCast:
11065 case CK_CPointerToObjCPointerCast:
11066 case CK_BlockPointerToObjCPointerCast:
11067 case CK_AnyPointerToBlockPointerCast:
11068 case CK_ObjCObjectLValueCast:
11069 case CK_FloatingRealToComplex:
11070 case CK_FloatingComplexToReal:
11071 case CK_FloatingComplexCast:
11072 case CK_FloatingComplexToIntegralComplex:
11073 case CK_IntegralRealToComplex:
11074 case CK_IntegralComplexCast:
11075 case CK_IntegralComplexToFloatingComplex:
11076 case CK_BuiltinFnToFnPtr:
11077 case CK_ZeroToOCLOpaqueType:
11078 case CK_NonAtomicToAtomic:
11079 case CK_AddressSpaceConversion:
11080 case CK_IntToOCLSampler:
11081 case CK_FixedPointCast:
11082 case CK_IntegralToFixedPoint:
11083 llvm_unreachable(
"invalid cast kind for integral value");
11087 case CK_LValueBitCast:
11088 case CK_ARCProduceObject:
11089 case CK_ARCConsumeObject:
11090 case CK_ARCReclaimReturnedObject:
11091 case CK_ARCExtendBlockObject:
11092 case CK_CopyAndAutoreleaseBlockObject:
11095 case CK_UserDefinedConversion:
11096 case CK_LValueToRValue:
11097 case CK_AtomicToNonAtomic:
11099 case CK_LValueToRValueBitCast:
11100 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11102 case CK_MemberPointerToBoolean:
11103 case CK_PointerToBoolean:
11104 case CK_IntegralToBoolean:
11105 case CK_FloatingToBoolean:
11106 case CK_BooleanToSignedIntegral:
11107 case CK_FloatingComplexToBoolean:
11108 case CK_IntegralComplexToBoolean: {
11112 uint64_t IntResult = BoolResult;
11113 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
11114 IntResult = (uint64_t)-1;
11115 return Success(IntResult, E);
11118 case CK_FixedPointToIntegral: {
11119 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
11123 llvm::APSInt Result = Src.convertToInt(
11124 Info.Ctx.getIntWidth(DestType),
11128 return Success(Result, E);
11131 case CK_FixedPointToBoolean: {
11134 if (!
Evaluate(Val, Info, SubExpr))
11139 case CK_IntegralCast: {
11140 if (!Visit(SubExpr))
11143 if (!Result.isInt()) {
11149 if (Result.isAddrLabelDiff())
11150 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
11152 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
11156 Result.getInt()), E);
11159 case CK_PointerToIntegral: {
11160 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
11166 if (LV.getLValueBase()) {
11171 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
11174 LV.Designator.setInvalid();
11175 LV.moveInto(Result);
11183 llvm_unreachable(
"Can't cast this!");
11188 case CK_IntegralComplexToReal: {
11192 return Success(C.getComplexIntReal(), E);
11195 case CK_FloatingToIntegral: {
11203 return Success(Value, E);
11207 llvm_unreachable(
"unknown cast resulting in integral value");
11210 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
11215 if (!LV.isComplexInt())
11217 return Success(LV.getComplexIntReal(), E);
11223 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11228 if (!LV.isComplexInt())
11230 return Success(LV.getComplexIntImag(), E);
11234 return Success(0, E);
11237 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
11241 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
11245 bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11255 if (!Result.isFixedPoint())
11258 APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
11261 return Success(Negated, E);
11267 return Success(!bres, E);
11272 bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11276 "Expected destination type to be a fixed point type");
11277 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
11280 case CK_FixedPointCast: {
11288 return Success(Result, E);
11290 case CK_IntegralToFixedPoint: {
11297 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
11299 if (Overflowed && !
HandleOverflow(Info, E, IntResult, DestType))
11302 return Success(IntResult, E);
11305 case CK_LValueToRValue:
11306 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11312 bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11316 Info.Ctx.getFixedPointSemantics(E->
getType());
11327 bool AddOverflow, ConversionOverflow;
11329 .
convert(ResultFXSema, &ConversionOverflow);
11330 if ((AddOverflow || ConversionOverflow) &&
11333 return Success(Result, E);
11338 llvm_unreachable(
"Should've exited before this");
11346 class FloatExprEvaluator
11347 :
public ExprEvaluatorBase<FloatExprEvaluator> {
11350 FloatExprEvaluator(EvalInfo &info, APFloat &
result)
11351 : ExprEvaluatorBaseTy(info),
Result(result) {}
11358 bool ZeroInitialization(
const Expr *E) {
11359 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
11363 bool VisitCallExpr(
const CallExpr *E);
11368 bool VisitCastExpr(
const CastExpr *E);
11379 return FloatExprEvaluator(Info, Result).Visit(E);
11386 llvm::APFloat &Result) {
11388 if (!S)
return false;
11396 fill = llvm::APInt(32, 0);
11397 else if (S->
getString().getAsInteger(0, fill))
11402 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
11404 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
11412 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
11414 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
11420 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
11423 return ExprEvaluatorBaseTy::VisitCallExpr(E);
11425 case Builtin::BI__builtin_huge_val:
11426 case Builtin::BI__builtin_huge_valf:
11427 case Builtin::BI__builtin_huge_vall:
11428 case Builtin::BI__builtin_huge_valf128:
11429 case Builtin::BI__builtin_inf:
11430 case Builtin::BI__builtin_inff:
11431 case Builtin::BI__builtin_infl:
11432 case Builtin::BI__builtin_inff128: {
11433 const llvm::fltSemantics &Sem =
11434 Info.Ctx.getFloatTypeSemantics(E->
getType());
11435 Result = llvm::APFloat::getInf(Sem);
11439 case Builtin::BI__builtin_nans:
11440 case Builtin::BI__builtin_nansf:
11441 case Builtin::BI__builtin_nansl:
11442 case Builtin::BI__builtin_nansf128:
11448 case Builtin::BI__builtin_nan:
11449 case Builtin::BI__builtin_nanf:
11450 case Builtin::BI__builtin_nanl:
11451 case Builtin::BI__builtin_nanf128:
11459 case Builtin::BI__builtin_fabs:
11460 case Builtin::BI__builtin_fabsf:
11461 case Builtin::BI__builtin_fabsl:
11462 case Builtin::BI__builtin_fabsf128:
11466 if (Result.isNegative())
11467 Result.changeSign();
11474 case Builtin::BI__builtin_copysign:
11475 case Builtin::BI__builtin_copysignf:
11476 case Builtin::BI__builtin_copysignl:
11477 case Builtin::BI__builtin_copysignf128: {
11482 Result.copySign(RHS);
11488 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
11493 Result = CV.FloatReal;
11500 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
11505 Result = CV.FloatImag;
11510 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
11511 Result = llvm::APFloat::getZero(Sem);
11515 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
11517 default:
return Error(E);
11523 Result.changeSign();
11528 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11530 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11534 if (!LHSOK && !Info.noteFailure())
11540 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
11545 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11550 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11552 case CK_IntegralToFloating: {
11559 case CK_FloatingCast: {
11560 if (!Visit(SubExpr))
11566 case CK_FloatingComplexToReal: {
11570 Result = V.getComplexFloatReal();
11581 class ComplexExprEvaluator
11582 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
11586 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
11587 : ExprEvaluatorBaseTy(info),
Result(Result) {}
11594 bool ZeroInitialization(
const Expr *E);
11601 bool VisitCastExpr(
const CastExpr *E);
11611 return ComplexExprEvaluator(Info, Result).Visit(E);
11614 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
11617 Result.makeComplexFloat();
11618 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
11619 Result.FloatReal = Zero;
11620 Result.FloatImag = Zero;
11622 Result.makeComplexInt();
11623 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
11624 Result.IntReal = Zero;
11625 Result.IntImag = Zero;
11630 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
11634 Result.makeComplexFloat();
11635 APFloat &Imag = Result.FloatImag;
11639 Result.FloatReal = APFloat(Imag.getSemantics());
11643 "Unexpected imaginary literal.");
11645 Result.makeComplexInt();
11646 APSInt &Imag = Result.IntImag;
11650 Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
11655 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11659 case CK_BaseToDerived:
11660 case CK_DerivedToBase:
11661 case CK_UncheckedDerivedToBase:
11664 case CK_ArrayToPointerDecay:
11665 case CK_FunctionToPointerDecay:
11666 case CK_NullToPointer:
11667 case CK_NullToMemberPointer:
11668 case CK_BaseToDerivedMemberPointer:
11669 case CK_DerivedToBaseMemberPointer:
11670 case CK_MemberPointerToBoolean:
11671 case CK_ReinterpretMemberPointer:
11672 case CK_ConstructorConversion:
11673 case CK_IntegralToPointer:
11674 case CK_PointerToIntegral:
11675 case CK_PointerToBoolean:
11677 case CK_VectorSplat:
11678 case CK_IntegralCast:
11679 case CK_BooleanToSignedIntegral:
11680 case CK_IntegralToBoolean:
11681 case CK_IntegralToFloating:
11682 case CK_FloatingToIntegral:
11683 case CK_FloatingToBoolean:
11684 case CK_FloatingCast:
11685 case CK_CPointerToObjCPointerCast:
11686 case CK_BlockPointerToObjCPointerCast:
11687 case CK_AnyPointerToBlockPointerCast:
11688 case CK_ObjCObjectLValueCast:
11689 case CK_FloatingComplexToReal:
11690 case CK_FloatingComplexToBoolean:
11691 case CK_IntegralComplexToReal:
11692 case CK_IntegralComplexToBoolean:
11693 case CK_ARCProduceObject:
11694 case CK_ARCConsumeObject:
11695 case CK_ARCReclaimReturnedObject:
11696 case CK_ARCExtendBlockObject:
11697 case CK_CopyAndAutoreleaseBlockObject:
11698 case CK_BuiltinFnToFnPtr:
11699 case CK_ZeroToOCLOpaqueType:
11700 case CK_NonAtomicToAtomic:
11701 case CK_AddressSpaceConversion:
11702 case CK_IntToOCLSampler:
11703 case CK_FixedPointCast:
11704 case CK_FixedPointToBoolean:
11705 case CK_FixedPointToIntegral:
11706 case CK_IntegralToFixedPoint:
11707 llvm_unreachable(
"invalid cast kind for complex value");
11709 case CK_LValueToRValue:
11710 case CK_AtomicToNonAtomic:
11712 case CK_LValueToRValueBitCast:
11713 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11716 case CK_LValueBitCast:
11717 case CK_UserDefinedConversion:
11720 case CK_FloatingRealToComplex: {
11721 APFloat &Real = Result.FloatReal;
11725 Result.makeComplexFloat();
11726 Result.FloatImag = APFloat(Real.getSemantics());
11730 case CK_FloatingComplexCast: {
11742 case CK_FloatingComplexToIntegralComplex: {
11749 Result.makeComplexInt();
11751 To, Result.IntReal) &&
11753 To, Result.IntImag);
11756 case CK_IntegralRealToComplex: {
11757 APSInt &Real = Result.IntReal;
11761 Result.makeComplexInt();
11762 Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
11766 case CK_IntegralComplexCast: {
11779 case CK_IntegralComplexToFloatingComplex: {
11786 Result.makeComplexFloat();
11788 To, Result.FloatReal) &&
11790 To, Result.FloatImag);
11794 llvm_unreachable(
"unknown cast resulting in complex value");
11797 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
11799 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
11803 bool LHSReal =
false, RHSReal =
false;
11808 APFloat &Real = Result.FloatReal;
11811 Result.makeComplexFloat();
11812 Result.FloatImag = APFloat(Real.getSemantics());
11815 LHSOK = Visit(E->
getLHS());
11817 if (!LHSOK && !Info.noteFailure())
11823 APFloat &Real = RHS.FloatReal;
11826 RHS.makeComplexFloat();
11827 RHS.FloatImag = APFloat(Real.getSemantics());
11831 assert(!(LHSReal && RHSReal) &&
11832 "Cannot have both operands of a complex operation be real.");
11834 default:
return Error(E);
11836 if (Result.isComplexFloat()) {
11837 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
11838 APFloat::rmNearestTiesToEven);
11840 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
11842 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
11843 APFloat::rmNearestTiesToEven);
11845 Result.getComplexIntReal() += RHS.getComplexIntReal();
11846 Result.getComplexIntImag() += RHS.getComplexIntImag();
11850 if (Result.isComplexFloat()) {
11851 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
11852 APFloat::rmNearestTiesToEven);
11854 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
11855 Result.getComplexFloatImag().changeSign();
11856 }
else if (!RHSReal) {
11857 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
11858 APFloat::rmNearestTiesToEven);
11861 Result.getComplexIntReal() -= RHS.getComplexIntReal();
11862 Result.getComplexIntImag() -= RHS.getComplexIntImag();
11866 if (Result.isComplexFloat()) {
11871 ComplexValue LHS =
Result;
11872 APFloat &A = LHS.getComplexFloatReal();
11873 APFloat &B = LHS.getComplexFloatImag();
11874 APFloat &
C = RHS.getComplexFloatReal();
11875 APFloat &D = RHS.getComplexFloatImag();
11876 APFloat &ResR = Result.getComplexFloatReal();
11877 APFloat &ResI = Result.getComplexFloatImag();
11879 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
11882 }
else if (RHSReal) {
11888 APFloat AC = A *
C;
11889 APFloat BD = B * D;
11890 APFloat AD = A * D;
11891 APFloat BC = B *
C;
11894 if (ResR.isNaN() && ResI.isNaN()) {
11895 bool Recalc =
false;
11896 if (A.isInfinity() || B.isInfinity()) {
11897 A = APFloat::copySign(
11898 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
11899 B = APFloat::copySign(
11900 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
11902 C = APFloat::copySign(APFloat(C.getSemantics()), C);
11904 D = APFloat::copySign(APFloat(D.getSemantics()), D);
11907 if (C.isInfinity() || D.isInfinity()) {
11908 C = APFloat::copySign(
11909 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
11910 D = APFloat::copySign(
11911 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
11913 A = APFloat::copySign(APFloat(A.getSemantics()), A);
11915 B = APFloat::copySign(APFloat(B.getSemantics()), B);
11918 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
11919 AD.isInfinity() || BC.isInfinity())) {
11921 A = APFloat::copySign(APFloat(A.getSemantics()), A);
11923 B = APFloat::copySign(APFloat(B.getSemantics()), B);
11925 C = APFloat::copySign(APFloat(C.getSemantics()), C);
11927 D = APFloat::copySign(APFloat(D.getSemantics()), D);
11931 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
11932 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
11937 ComplexValue LHS =
Result;
11938 Result.getComplexIntReal() =
11939 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
11940 LHS.getComplexIntImag() * RHS.getComplexIntImag());
11941 Result.getComplexIntImag() =
11942 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
11943 LHS.getComplexIntImag() * RHS.getComplexIntReal());
11947 if (Result.isComplexFloat()) {
11952 ComplexValue LHS =
Result;
11953 APFloat &A = LHS.getComplexFloatReal();
11954 APFloat &B = LHS.getComplexFloatImag();
11955 APFloat &
C = RHS.getComplexFloatReal();
11956 APFloat &D = RHS.getComplexFloatImag();
11957 APFloat &ResR = Result.getComplexFloatReal();
11958 APFloat &ResI = Result.getComplexFloatImag();
11965 B = APFloat::getZero(A.getSemantics());
11968 APFloat MaxCD = maxnum(
abs(C),
abs(D));
11969 if (MaxCD.isFinite()) {
11970 DenomLogB =
ilogb(MaxCD);
11971 C =
scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
11972 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
11974 APFloat Denom = C * C + D * D;
11975 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB,
11976 APFloat::rmNearestTiesToEven);
11977 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB,
11978 APFloat::rmNearestTiesToEven);
11979 if (ResR.isNaN() && ResI.isNaN()) {
11980 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
11981 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
11982 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
11983 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
11985 A = APFloat::copySign(
11986 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
11987 B = APFloat::copySign(
11988 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
11989 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
11990 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
11991 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
11992 C = APFloat::copySign(
11993 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
11994 D = APFloat::copySign(
11995 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
11996 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
11997 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
12002 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
12003 return Error(E, diag::note_expr_divide_by_zero);
12005 ComplexValue LHS =
Result;
12006 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
12007 RHS.getComplexIntImag() * RHS.getComplexIntImag();
12008 Result.getComplexIntReal() =
12009 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
12010 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
12011 Result.getComplexIntImag() =
12012 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
12013 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
12021 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12035 if (Result.isComplexFloat()) {
12036 Result.getComplexFloatReal().changeSign();
12037 Result.getComplexFloatImag().changeSign();
12040 Result.getComplexIntReal() = -Result.getComplexIntReal();
12041 Result.getComplexIntImag() = -Result.getComplexIntImag();
12045 if (Result.isComplexFloat())
12046 Result.getComplexFloatImag().changeSign();
12048 Result.getComplexIntImag() = -Result.getComplexIntImag();
12053 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
12056 Result.makeComplexFloat();
12062 Result.makeComplexInt();
12070 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
12079 class AtomicExprEvaluator :
12080 public ExprEvaluatorBase<AtomicExprEvaluator> {
12081 const LValue *This;
12084 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
12085 : ExprEvaluatorBaseTy(Info), This(This),
Result(Result) {}
12092 bool ZeroInitialization(
const Expr *E) {
12101 bool VisitCastExpr(
const CastExpr *E) {
12104 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12105 case CK_NonAtomicToAtomic:
12116 return AtomicExprEvaluator(Info, This, Result).Visit(E);
12125 class VoidExprEvaluator
12126 :
public ExprEvaluatorBase<VoidExprEvaluator> {
12128 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
12130 bool Success(
const APValue &
V,
const Expr *e) {
return true; }
12132 bool ZeroInitialization(
const Expr *E) {
return true; }
12134 bool VisitCastExpr(
const CastExpr *E) {
12137 return ExprEvaluatorBaseTy::VisitCastExpr(E);
12144 bool VisitCallExpr(
const CallExpr *E) {
12147 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12148 case Builtin::BI__assume:
12149 case Builtin::BI__builtin_assume:
12159 return VoidExprEvaluator(Info).Visit(E);
12174 LV.moveInto(Result);
12179 if (!IntExprEvaluator(Info, Result).Visit(E))
12185 LV.moveInto(Result);
12187 llvm::APFloat F(0.0);
12195 C.moveInto(Result);
12197 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
12202 P.moveInto(Result);
12217 if (!Info.getLangOpts().CPlusPlus11)
12218 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
12233 }
else if (Info.getLangOpts().CPlusPlus11) {
12234 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
12237 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
12248 const Expr *E,
bool AllowNonLiteralTypes) {
12287 LV.setFrom(Info.Ctx, Result);
12302 L->getType()->isUnsignedIntegerType()));
12378 bool InConstantContext)
const {
12379 assert(!isValueDependent() &&
12380 "Expression evaluator can't be called on a dependent expression.");
12381 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
12382 Info.InConstantContext = InConstantContext;
12387 bool InConstantContext)
const {
12388 assert(!isValueDependent() &&
12389 "Expression evaluator can't be called on a dependent expression.");
12397 bool InConstantContext)
const {
12398 assert(!isValueDependent() &&
12399 "Expression evaluator can't be called on a dependent expression.");
12400 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
12401 Info.InConstantContext = InConstantContext;
12407 bool InConstantContext)
const {
12408 assert(!isValueDependent() &&
12409 "Expression evaluator can't be called on a dependent expression.");
12410 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
12411 Info.InConstantContext = InConstantContext;
12417 bool InConstantContext)
const {
12418 assert(!isValueDependent() &&
12419 "Expression evaluator can't be called on a dependent expression.");
12421 if (!getType()->isRealFloatingType())
12426 !ExprResult.Val.isFloat() ||
12430 Result = ExprResult.Val.getFloat();
12435 bool InConstantContext)
const {
12436 assert(!isValueDependent() &&
12437 "Expression evaluator can't be called on a dependent expression.");
12439 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
12440 Info.InConstantContext = InConstantContext;
12448 LV.moveInto(Result.Val);
12454 assert(!isValueDependent() &&
12455 "Expression evaluator can't be called on a dependent expression.");
12457 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
12458 EvalInfo Info(Ctx, Result, EM);
12459 Info.InConstantContext =
true;
12461 if (!::
Evaluate(Result.Val, Info,
this))
12471 assert(!isValueDependent() &&
12472 "Expression evaluator can't be called on a dependent expression.");
12476 if (isRValue() && (getType()->isArrayType() || getType()->
isRecordType()) &&
12481 EStatus.
Diag = &Notes;
12483 EvalInfo InitInfo(Ctx, EStatus, VD->
isConstexpr()
12484 ? EvalInfo::EM_ConstantExpression
12485 : EvalInfo::EM_ConstantFold);
12486 InitInfo.setEvaluatingDecl(VD, Value);
12487 InitInfo.InConstantContext =
true;
12516 assert(!isValueDependent() &&
12517 "Expression evaluator can't be called on a dependent expression.");
12526 assert(!isValueDependent() &&
12527 "Expression evaluator can't be called on a dependent expression.");
12530 EVResult.Diag =
Diag;
12531 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
12532 Info.InConstantContext =
true;
12536 assert(Result &&
"Could not evaluate expression");
12537 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
12539 return EVResult.Val.getInt();
12544 assert(!isValueDependent() &&
12545 "Expression evaluator can't be called on a dependent expression.");
12548 EVResult.Diag =
Diag;
12549 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
12550 Info.InConstantContext =
true;
12554 assert(Result &&
"Could not evaluate expression");
12555 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
12557 return EVResult.Val.getInt();
12561 assert(!isValueDependent() &&
12562 "Expression evaluator can't be called on a dependent expression.");
12567 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
12573 assert(Val.isLValue());
12601 IK_ICEIfUnevaluated,
12617 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
12622 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
12624 Info.InConstantContext =
true;
12633 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
12638 #define ABSTRACT_STMT(Node) 12639 #define STMT(Node, Base) case Expr::Node##Class: 12640 #define EXPR(Node, Base) 12641 #include "clang/AST/StmtNodes.inc" 12642 case Expr::PredefinedExprClass:
12643 case Expr::FloatingLiteralClass:
12644 case Expr::ImaginaryLiteralClass:
12645 case Expr::StringLiteralClass:
12646 case Expr::ArraySubscriptExprClass:
12647 case Expr::OMPArraySectionExprClass:
12648 case Expr::MemberExprClass:
12649 case Expr::CompoundAssignOperatorClass:
12650 case Expr::CompoundLiteralExprClass:
12651 case Expr::ExtVectorElementExprClass:
12652 case Expr::DesignatedInitExprClass:
12653 case Expr::ArrayInitLoopExprClass:
12654 case Expr::ArrayInitIndexExprClass:
12655 case Expr::NoInitExprClass:
12656 case Expr::DesignatedInitUpdateExprClass:
12657 case Expr::ImplicitValueInitExprClass:
12658 case Expr::ParenListExprClass:
12659 case Expr::VAArgExprClass:
12660 case Expr::AddrLabelExprClass:
12661 case Expr::StmtExprClass:
12662 case Expr::CXXMemberCallExprClass:
12663 case Expr::CUDAKernelCallExprClass:
12664 case Expr::CXXDynamicCastExprClass:
12665 case Expr::CXXTypeidExprClass:
12666 case Expr::CXXUuidofExprClass:
12667 case Expr::MSPropertyRefExprClass:
12668 case Expr::MSPropertySubscriptExprClass:
12669 case Expr::CXXNullPtrLiteralExprClass:
12670 case Expr::UserDefinedLiteralClass:
12671 case Expr::CXXThisExprClass:
12672 case Expr::CXXThrowExprClass:
12673 case Expr::CXXNewExprClass:
12674 case Expr::CXXDeleteExprClass:
12675 case Expr::CXXPseudoDestructorExprClass:
12676 case Expr::UnresolvedLookupExprClass:
12677 case Expr::TypoExprClass:
12678 case Expr::DependentScopeDeclRefExprClass:
12679 case Expr::CXXConstructExprClass:
12680 case Expr::CXXInheritedCtorInitExprClass:
12681 case Expr::CXXStdInitializerListExprClass:
12682 case Expr::CXXBindTemporaryExprClass:
12683 case Expr::ExprWithCleanupsClass:
12684 case Expr::CXXTemporaryObjectExprClass:
12685 case Expr::CXXUnresolvedConstructExprClass:
12686 case Expr::CXXDependentScopeMemberExprClass:
12687 case Expr::UnresolvedMemberExprClass:
12688 case Expr::ObjCStringLiteralClass:
12689 case Expr::ObjCBoxedExprClass:
12690 case Expr::ObjCArrayLiteralClass:
12691 case Expr::ObjCDictionaryLiteralClass:
12692 case Expr::ObjCEncodeExprClass:
12693 case Expr::ObjCMessageExprClass:
12694 case Expr::ObjCSelectorExprClass:
12695 case Expr::ObjCProtocolExprClass:
12696 case Expr::ObjCIvarRefExprClass:
12697 case Expr::ObjCPropertyRefExprClass:
12698 case Expr::ObjCSubscriptRefExprClass:
12699 case Expr::ObjCIsaExprClass:
12700 case Expr::ObjCAvailabilityCheckExprClass:
12701 case Expr::ShuffleVectorExprClass:
12702 case Expr::ConvertVectorExprClass:
12703 case Expr::BlockExprClass:
12705 case Expr::OpaqueValueExprClass:
12706 case Expr::PackExpansionExprClass:
12707 case Expr::SubstNonTypeTemplateParmPackExprClass:
12708 case Expr::FunctionParmPackExprClass:
12709 case Expr::AsTypeExprClass:
12710 case Expr::ObjCIndirectCopyRestoreExprClass:
12711 case Expr::MaterializeTemporaryExprClass:
12712 case Expr::PseudoObjectExprClass:
12713 case Expr::AtomicExprClass:
12714 case Expr::LambdaExprClass:
12715 case Expr::CXXFoldExprClass:
12716 case Expr::CoawaitExprClass:
12717 case Expr::DependentCoawaitExprClass:
12718 case Expr::CoyieldExprClass:
12721 case Expr::InitListExprClass: {
12727 if (cast<InitListExpr>(E)->getNumInits() == 1)
12728 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
12732 case Expr::SizeOfPackExprClass:
12733 case Expr::GNUNullExprClass:
12734 case Expr::SourceLocExprClass:
12737 case Expr::SubstNonTypeTemplateParmExprClass:
12739 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
12741 case Expr::ConstantExprClass:
12742 return CheckICE(cast<ConstantExpr>(E)->getSubExpr(), Ctx);
12744 case Expr::ParenExprClass:
12745 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
12746 case Expr::GenericSelectionExprClass:
12747 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
12748 case Expr::IntegerLiteralClass:
12749 case Expr::FixedPointLiteralClass:
12750 case Expr::CharacterLiteralClass:
12751 case Expr::ObjCBoolLiteralExprClass:
12752 case Expr::CXXBoolLiteralExprClass:
12753 case Expr::CXXScalarValueInitExprClass:
12754 case Expr::TypeTraitExprClass:
12755 case Expr::ArrayTypeTraitExprClass:
12756 case Expr::ExpressionTraitExprClass:
12757 case Expr::CXXNoexceptExprClass:
12759 case Expr::CallExprClass:
12760 case Expr::CXXOperatorCallExprClass: {
12764 const CallExpr *CE = cast<CallExpr>(E);
12769 case Expr::DeclRefExprClass: {
12770 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
12772 const ValueDecl *D = cast<DeclRefExpr>(E)->getDecl();
12778 if (isa<ParmVarDecl>(D))
12779 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
12784 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
12785 if (!Dcl->getType()->isIntegralOrEnumerationType())
12786 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
12794 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
12799 case Expr::UnaryOperatorClass: {
12822 llvm_unreachable(
"invalid unary operator class");
12824 case Expr::OffsetOfExprClass: {
12833 case Expr::UnaryExprOrTypeTraitExprClass: {
12840 case Expr::BinaryOperatorClass: {
12885 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
12888 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
12889 if (REval.isSigned() && REval.isAllOnesValue()) {
12891 if (LEval.isMinSignedValue())
12892 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
12900 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
12901 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
12907 return Worst(LHSResult, RHSResult);
12913 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
12923 return Worst(LHSResult, RHSResult);
12926 llvm_unreachable(
"invalid binary operator kind");
12928 case Expr::ImplicitCastExprClass:
12929 case Expr::CStyleCastExprClass:
12930 case Expr::CXXFunctionalCastExprClass:
12931 case Expr::CXXStaticCastExprClass:
12932 case Expr::CXXReinterpretCastExprClass:
12933 case Expr::CXXConstCastExprClass:
12934 case Expr::ObjCBridgedCastExprClass: {
12935 const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
12936 if (isa<ExplicitCastExpr>(E)) {
12941 APSInt IgnoredVal(DestWidth, !DestSigned);
12946 if (FL->getValue().convertToInteger(IgnoredVal,
12947 llvm::APFloat::rmTowardZero,
12948 &Ignored) & APFloat::opInvalidOp)
12953 switch (cast<CastExpr>(E)->getCastKind()) {
12954 case CK_LValueToRValue:
12955 case CK_AtomicToNonAtomic:
12956 case CK_NonAtomicToAtomic:
12958 case CK_IntegralToBoolean:
12959 case CK_IntegralCast:
12965 case Expr::BinaryConditionalOperatorClass: {
12968 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
12970 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
12971 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
12972 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
12974 return FalseResult;
12976 case Expr::ConditionalOperatorClass: {
12984 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
12987 if (CondResult.Kind == IK_NotICE)
12993 if (TrueResult.Kind == IK_NotICE)
12995 if (FalseResult.Kind == IK_NotICE)
12996 return FalseResult;
12997 if (CondResult.Kind == IK_ICEIfUnevaluated)
12999 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
13005 return FalseResult;
13008 case Expr::CXXDefaultArgExprClass:
13009 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
13010 case Expr::CXXDefaultInitExprClass:
13011 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
13012 case Expr::ChooseExprClass: {
13013 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
13015 case Expr::BuiltinBitCastExprClass: {
13016 if (!checkBitCastConstexprEligibility(
nullptr, Ctx, cast<CastExpr>(E)))
13018 return CheckICE(cast<CastExpr>(E)->getSubExpr(), Ctx);
13022 llvm_unreachable(
"Invalid StmtClass!");
13028 llvm::APSInt *Value,
13039 if (!Result.
isInt()) {
13044 if (Value) *Value = Result.
getInt();
13050 assert(!isValueDependent() &&
13051 "Expression evaluator can't be called on a dependent expression.");
13057 if (D.Kind != IK_ICE) {
13058 if (Loc) *Loc = D.Loc;
13066 assert(!isValueDependent() &&
13067 "Expression evaluator can't be called on a dependent expression.");
13072 if (!isIntegerConstantExpr(Ctx, Loc))
13081 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
13082 Info.InConstantContext =
true;
13084 if (!::
EvaluateAsInt(
this, ExprResult, Ctx, SE_AllowSideEffects, Info))
13085 llvm_unreachable(
"ICE cannot be evaluated!");
13087 Value = ExprResult.Val.getInt();
13092 assert(!isValueDependent() &&
13093 "Expression evaluator can't be called on a dependent expression.");
13095 return CheckICE(
this, Ctx).Kind == IK_ICE;
13100 assert(!isValueDependent() &&
13101 "Expression evaluator can't be called on a dependent expression.");
13110 Status.Diag = &Diags;
13111 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
13116 if (!Diags.empty()) {
13117 IsConstExpr =
false;
13118 if (Loc) *Loc = Diags[0].first;
13119 }
else if (!IsConstExpr) {
13121 if (Loc) *Loc = getExprLoc();
13124 return IsConstExpr;
13130 const Expr *This)
const {
13131 assert(!isValueDependent() &&
13132 "Expression evaluator can't be called on a dependent expression.");
13135 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
13136 Info.InConstantContext =
true;
13139 const LValue *ThisPtr =
nullptr;
13143 assert(MD &&
"Don't provide `this` for non-methods.");
13144 assert(!MD->isStatic() &&
"Don't provide `this` for static methods.");
13147 ThisPtr = &ThisVal;
13148 if (Info.EvalStatus.HasSideEffects)
13152 ArgVector ArgValues(Args.size());
13155 if ((*I)->isValueDependent() ||
13156 !
Evaluate(ArgValues[I - Args.begin()], Info, *I))
13158 ArgValues[I - Args.begin()] =
APValue();
13159 if (Info.EvalStatus.HasSideEffects)
13164 CallStackFrame Frame(Info, Callee->
getLocation(), Callee, ThisPtr,
13166 return Evaluate(Value, Info,
this) && !Info.EvalStatus.HasSideEffects;
13179 Status.
Diag = &Diags;
13182 EvalInfo::EM_PotentialConstantExpression);
13183 Info.InConstantContext =
true;
13192 This.set({&VIE, Info.CurrentCall->Index});
13200 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
13205 Args, FD->
getBody(), Info, Scratch,
nullptr);
13208 return Diags.empty();
13216 "Expression evaluator can't be called on a dependent expression.");
13219 Status.Diag = &Diags;
13222 EvalInfo::EM_PotentialConstantExpressionUnevaluated);
13223 Info.InConstantContext =
true;
13227 ArgVector ArgValues(0);
13228 bool Success =
EvaluateArgs(Args, ArgValues, Info, FD);
13231 "Failed to set up arguments for potential constant evaluation");
13232 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
13236 return Diags.empty();
13240 unsigned Type)
const {
13241 if (!getType()->isPointerType())
13245 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.
Represents a function declaration or definition.
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.
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.
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...
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
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.
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)
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
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
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)?
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 bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result)
Extract the designated sub-object of an rvalue.
static ObjectUnderConstruction getTombstoneKey()
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
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...
DiagnosticsEngine & getDiagnostics() const
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
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...
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.
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)
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 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()
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
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
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]).
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size)
Get the size of the given type in char units.
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().
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.
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.
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
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.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
bool isReferenceType() const
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.
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.
SourceLocation getBeginLoc() const LLVM_READONLY
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.
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)
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 const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. ...
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.
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.
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal)
Perform an lvalue-to-rvalue conversion on the given glvalue.
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
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)
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
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 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.
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 isEquality() const
True iff the comparison category is an equality comparison.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
bool isLambdaCallOperator(const CXXMethodDecl *MD)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base)
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.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result)
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point...
Represents the this expression in C++.
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 bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage=Expr::EvaluateForCodeGen, SourceLocation SubobjectLoc=SourceLocation())
Check that this core constant expression value is a valid value for a constant expression.
QualType getElementType() const
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr...
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.
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.
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.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
unsigned getNumInits() const
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
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
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, Expr::ConstExprUsage Usage)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
DeclContext * getDeclContext()
uint32_t getCodeUnit(size_t i) const
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
bool isAnyComplexType() const
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.
static bool diagnoseUnreadableFields(EvalInfo &Info, const Expr *E, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
PartialDiagnostic::StorageAllocator & getDiagAllocator()
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.
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.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const Expr * getSubExpr() const
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
void toString(llvm::SmallVectorImpl< char > &Str) const
static APValue & createTemporary(const KeyTy *Key, bool IsLifetimeExtended, LValue &LV, CallStackFrame &Frame)
A helper function to create a temporary and set an LValue.
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...
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 isOrdered() const
True iff the comparison category is a relational comparison.
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
CastKind getCastKind() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
APValue & getUnionValue()
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.
const ParmVarDecl * getParamDecl(unsigned i) const
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...
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
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
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
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.
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)
Represents an element in a path from a derived class to a base class.
AddrLabelExpr - The GNU address of label extension, representing &&label.
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;...
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...
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.
EvalResult is a struct with detailed info about an evaluated expression.
static bool isZeroSized(const LValue &Value)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
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...
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.
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 checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
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 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...
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)
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)
unsigned getConstexprBacktraceLimit() const
Retrieve the maximum number of constexpr evaluation notes to emit along with a given diagnostic...
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...
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.
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)
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.
unsigned getNumElements() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
unsigned getNumComponents() const
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 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
static bool isComparisonOp(Opcode Opc)
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()
Attr - This represents one attribute.
static void describeCall(CallStackFrame *Frame, raw_ostream &Out)
Produce a string describing the given constexpr call.
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