48 #include "llvm/Support/SaveAndRestore.h" 49 #include "llvm/Support/raw_ostream.h" 53 #define DEBUG_TYPE "exprconstant" 55 using namespace clang;
63 struct CallStackFrame;
76 for (
auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
77 Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
90 dyn_cast<MaterializeTemporaryExpr>(Base)) {
93 const Expr *Temp = MTE->GetTemporaryExpr();
98 if (!Adjustments.empty())
117 return dyn_cast<
FieldDecl>(getAsBaseOrMember(E).getPointer());
122 return dyn_cast<
CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
127 return getAsBaseOrMember(E).getInt();
131 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
133 return Callee ? Callee->
getAttr<AllocSizeAttr>() :
nullptr;
140 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
148 if (
const auto *FE = dyn_cast<FullExpr>(E))
151 if (
const auto *Cast = dyn_cast<CastExpr>(E))
154 if (
const auto *CE = dyn_cast<CallExpr>(E))
155 return getAllocSizeAttr(CE) ? CE :
nullptr;
169 static const uint64_t AssumedSizeForUnsizedArray =
180 bool &FirstEntryIsUnsizedArray) {
183 assert(!isBaseAnAllocSizeCall(Base) &&
184 "Unsized arrays shouldn't appear here");
185 unsigned MostDerivedLength = 0;
186 Type = getType(Base);
188 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
192 MostDerivedLength = I + 1;
195 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
196 ArraySize = CAT->getSize().getZExtValue();
198 assert(I == 0 &&
"unexpected unsized array designator");
199 FirstEntryIsUnsizedArray =
true;
200 ArraySize = AssumedSizeForUnsizedArray;
206 MostDerivedLength = I + 1;
208 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
209 Type = FD->getType();
211 MostDerivedLength = I + 1;
219 return MostDerivedLength;
224 CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex,
225 CSK_This, CSK_Real, CSK_Imag
229 struct SubobjectDesignator {
233 unsigned Invalid : 1;
236 unsigned IsOnePastTheEnd : 1;
239 unsigned FirstEntryIsAnUnsizedArray : 1;
242 unsigned MostDerivedIsArrayElement : 1;
246 unsigned MostDerivedPathLength : 28;
255 uint64_t MostDerivedArraySize;
265 SubobjectDesignator() : Invalid(
true) {}
267 explicit SubobjectDesignator(
QualType T)
268 : Invalid(
false), IsOnePastTheEnd(
false),
269 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
270 MostDerivedPathLength(0), MostDerivedArraySize(0),
271 MostDerivedType(T) {}
275 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
276 MostDerivedPathLength(0), MostDerivedArraySize(0) {
277 assert(V.
isLValue() &&
"Non-LValue used to make an LValue designator?");
281 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
283 bool IsArray =
false;
284 bool FirstIsUnsizedArray =
false;
285 MostDerivedPathLength = findMostDerivedSubobject(
287 MostDerivedType, IsArray, FirstIsUnsizedArray);
288 MostDerivedIsArrayElement = IsArray;
289 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
301 bool isMostDerivedAnUnsizedArray()
const {
302 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
303 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
308 uint64_t getMostDerivedArraySize()
const {
309 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
310 return MostDerivedArraySize;
314 bool isOnePastTheEnd()
const {
318 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
319 Entries[MostDerivedPathLength - 1].ArrayIndex == MostDerivedArraySize)
327 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
328 if (Invalid || isMostDerivedAnUnsizedArray())
334 bool IsArray = MostDerivedPathLength == Entries.size() &&
335 MostDerivedIsArrayElement;
336 uint64_t ArrayIndex =
337 IsArray ? Entries.back().ArrayIndex : (uint64_t)IsOnePastTheEnd;
339 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
340 return {ArrayIndex, ArraySize - ArrayIndex};
344 bool isValidSubobject()
const {
347 return !isOnePastTheEnd();
355 assert(!Invalid &&
"invalid designator has no subobject type");
356 return MostDerivedPathLength == Entries.size()
364 Entry.ArrayIndex = 0;
365 Entries.push_back(Entry);
369 MostDerivedIsArrayElement =
true;
370 MostDerivedArraySize = CAT->
getSize().getZExtValue();
371 MostDerivedPathLength = Entries.size();
375 void addUnsizedArrayUnchecked(
QualType ElemTy) {
377 Entry.ArrayIndex = 0;
378 Entries.push_back(Entry);
380 MostDerivedType = ElemTy;
381 MostDerivedIsArrayElement =
true;
385 MostDerivedArraySize = AssumedSizeForUnsizedArray;
386 MostDerivedPathLength = Entries.size();
390 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
393 Entry.BaseOrMember = Value.getOpaqueValue();
394 Entries.push_back(Entry);
397 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
398 MostDerivedType = FD->getType();
399 MostDerivedIsArrayElement =
false;
400 MostDerivedArraySize = 0;
401 MostDerivedPathLength = Entries.size();
405 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
407 Entry.ArrayIndex = Imag;
408 Entries.push_back(Entry);
412 MostDerivedType = EltTy;
413 MostDerivedIsArrayElement =
true;
414 MostDerivedArraySize = 2;
415 MostDerivedPathLength = Entries.size();
417 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
418 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
421 void adjustIndex(EvalInfo &Info,
const Expr *E, APSInt N) {
422 if (Invalid || !N)
return;
423 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
424 if (isMostDerivedAnUnsizedArray()) {
425 diagnoseUnsizedArrayPointerArithmetic(Info, E);
429 Entries.back().ArrayIndex += TruncatedN;
436 bool IsArray = MostDerivedPathLength == Entries.size() &&
437 MostDerivedIsArrayElement;
438 uint64_t ArrayIndex =
439 IsArray ? Entries.back().ArrayIndex : (uint64_t)IsOnePastTheEnd;
441 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
443 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
446 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
447 (llvm::APInt&)N += ArrayIndex;
448 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
449 diagnosePointerArithmetic(Info, E, N);
454 ArrayIndex += TruncatedN;
455 assert(ArrayIndex <= ArraySize &&
456 "bounds check succeeded for out-of-bounds index");
459 Entries.back().ArrayIndex = ArrayIndex;
461 IsOnePastTheEnd = (ArrayIndex != 0);
466 struct CallStackFrame {
470 CallStackFrame *Caller;
484 typedef std::pair<const void *, unsigned> MapKeyTy;
485 typedef std::map<MapKeyTy, APValue>
MapTy;
497 unsigned CurTempVersion = TempVersionStack.back();
499 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
501 void pushTempVersion() {
502 TempVersionStack.push_back(++CurTempVersion);
505 void popTempVersion() {
506 TempVersionStack.pop_back();
517 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
526 APValue *getTemporary(
const void *Key,
unsigned Version) {
527 MapKeyTy KV(Key, Version);
528 auto LB = Temporaries.lower_bound(KV);
529 if (LB != Temporaries.end() && LB->first == KV)
533 assert((LB == Temporaries.end() || LB->first.first != Key) &&
534 (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) &&
535 "Element with key 'Key' found in map");
540 APValue *getCurrentTemporary(
const void *Key) {
541 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
542 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
543 return &std::prev(UB)->second;
548 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
549 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
550 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
551 return std::prev(UB)->first.second;
559 class ThisOverrideRAII {
561 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
562 : Frame(Frame), OldThis(Frame.This) {
564 Frame.This = NewThis;
566 ~ThisOverrideRAII() {
567 Frame.This = OldThis;
570 CallStackFrame &Frame;
571 const LValue *OldThis;
576 class OptionalDiagnostic {
590 OptionalDiagnostic &
operator<<(
const APSInt &I) {
594 *Diag << StringRef(Buffer.data(), Buffer.size());
599 OptionalDiagnostic &
operator<<(
const APFloat &F) {
608 llvm::APFloat::semanticsPrecision(F.getSemantics());
609 precision = (precision * 59 + 195) / 196;
611 F.toString(Buffer, precision);
612 *Diag << StringRef(Buffer.data(), Buffer.size());
620 llvm::PointerIntPair<APValue*, 1, bool>
Value;
623 Cleanup(
APValue *Val,
bool IsLifetimeExtended)
624 :
Value(Val, IsLifetimeExtended) {}
626 bool isLifetimeExtended()
const {
return Value.getInt(); }
628 *Value.getPointer() =
APValue();
653 CallStackFrame *CurrentCall;
656 unsigned CallStackDepth;
659 unsigned NextCallIndex;
668 CallStackFrame BottomFrame;
684 typedef std::pair<APValue::LValueBase, std::pair<unsigned, unsigned>>
691 struct EvaluatingConstructorRAII {
693 EvaluatingObject Object;
695 EvaluatingConstructorRAII(EvalInfo &EI, EvaluatingObject Object)
696 : EI(EI), Object(Object) {
697 DidInsert = EI.EvaluatingConstructors.insert(Object).second;
699 ~EvaluatingConstructorRAII() {
700 if (DidInsert) EI.EvaluatingConstructors.erase(Object);
706 return EvaluatingConstructors.count(
707 EvaluatingObject(Decl, {CallIndex, Version}));
712 uint64_t ArrayInitIndex = -1;
716 bool HasActiveDiagnostic;
720 bool HasFoldFailureDiagnostic;
723 bool IsSpeculativelyEvaluating;
727 bool InConstantContext;
729 enum EvaluationMode {
732 EM_ConstantExpression,
738 EM_PotentialConstantExpression,
747 EM_EvaluateForOverflow,
751 EM_IgnoreSideEffects,
758 EM_ConstantExpressionUnevaluated,
767 EM_PotentialConstantExpressionUnevaluated,
772 bool checkingPotentialConstantExpression()
const {
773 return EvalMode == EM_PotentialConstantExpression ||
774 EvalMode == EM_PotentialConstantExpressionUnevaluated;
780 bool checkingForOverflow() {
return EvalMode == EM_EvaluateForOverflow; }
783 : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(
nullptr),
784 CallStackDepth(0), NextCallIndex(1),
785 StepsLeft(getLangOpts().ConstexprStepLimit),
787 EvaluatingDecl((
const ValueDecl *)
nullptr),
788 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
789 HasFoldFailureDiagnostic(
false), IsSpeculativelyEvaluating(
false),
790 InConstantContext(
false), EvalMode(Mode) {}
793 EvaluatingDecl = Base;
794 EvaluatingDeclValue = &
Value;
795 EvaluatingConstructors.insert({Base, {0, 0}});
803 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
805 if (NextCallIndex == 0) {
807 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
810 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
812 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
813 << getLangOpts().ConstexprCallDepth;
817 CallStackFrame *getCallFrame(
unsigned CallIndex) {
818 assert(CallIndex &&
"no call index in getCallFrame");
821 CallStackFrame *Frame = CurrentCall;
822 while (Frame->Index > CallIndex)
823 Frame = Frame->Caller;
824 return (Frame->Index == CallIndex) ? Frame :
nullptr;
827 bool nextStep(
const Stmt *S) {
829 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
840 EvalStatus.
Diag->push_back(std::make_pair(Loc, PD));
841 return EvalStatus.
Diag->back().second;
845 void addCallStack(
unsigned Limit);
849 unsigned ExtraNotes,
bool IsCCEDiag) {
851 if (EvalStatus.
Diag) {
858 if (!EvalStatus.
Diag->empty()) {
860 case EM_ConstantFold:
861 case EM_IgnoreSideEffects:
862 case EM_EvaluateForOverflow:
863 if (!HasFoldFailureDiagnostic)
867 case EM_ConstantExpression:
868 case EM_PotentialConstantExpression:
869 case EM_ConstantExpressionUnevaluated:
870 case EM_PotentialConstantExpressionUnevaluated:
871 HasActiveDiagnostic =
false;
872 return OptionalDiagnostic();
876 unsigned CallStackNotes = CallStackDepth - 1;
879 CallStackNotes =
std::min(CallStackNotes, Limit + 1);
880 if (checkingPotentialConstantExpression())
883 HasActiveDiagnostic =
true;
884 HasFoldFailureDiagnostic = !IsCCEDiag;
885 EvalStatus.
Diag->clear();
886 EvalStatus.
Diag->reserve(1 + ExtraNotes + CallStackNotes);
887 addDiag(Loc, DiagId);
888 if (!checkingPotentialConstantExpression())
890 return OptionalDiagnostic(&(*EvalStatus.
Diag)[0].second);
892 HasActiveDiagnostic =
false;
893 return OptionalDiagnostic();
899 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
900 unsigned ExtraNotes = 0) {
901 return Diag(Loc, DiagId, ExtraNotes,
false);
905 = diag::note_invalid_subexpr_in_const_expr,
906 unsigned ExtraNotes = 0) {
909 HasActiveDiagnostic =
false;
910 return OptionalDiagnostic();
919 = diag::note_invalid_subexpr_in_const_expr,
920 unsigned ExtraNotes = 0) {
923 if (!EvalStatus.
Diag || !EvalStatus.
Diag->empty()) {
924 HasActiveDiagnostic =
false;
925 return OptionalDiagnostic();
927 return Diag(Loc, DiagId, ExtraNotes,
true);
930 = diag::note_invalid_subexpr_in_const_expr,
931 unsigned ExtraNotes = 0) {
932 return CCEDiag(E->
getExprLoc(), DiagId, ExtraNotes);
936 if (!HasActiveDiagnostic)
937 return OptionalDiagnostic();
938 return OptionalDiagnostic(&addDiag(Loc, DiagId));
943 if (HasActiveDiagnostic) {
944 EvalStatus.
Diag->insert(EvalStatus.
Diag->end(),
945 Diags.begin(), Diags.end());
951 bool keepEvaluatingAfterSideEffect() {
953 case EM_PotentialConstantExpression:
954 case EM_PotentialConstantExpressionUnevaluated:
955 case EM_EvaluateForOverflow:
956 case EM_IgnoreSideEffects:
959 case EM_ConstantExpression:
960 case EM_ConstantExpressionUnevaluated:
961 case EM_ConstantFold:
964 llvm_unreachable(
"Missed EvalMode case");
969 bool noteSideEffect() {
971 return keepEvaluatingAfterSideEffect();
975 bool keepEvaluatingAfterUndefinedBehavior() {
977 case EM_EvaluateForOverflow:
978 case EM_IgnoreSideEffects:
979 case EM_ConstantFold:
982 case EM_PotentialConstantExpression:
983 case EM_PotentialConstantExpressionUnevaluated:
984 case EM_ConstantExpression:
985 case EM_ConstantExpressionUnevaluated:
988 llvm_unreachable(
"Missed EvalMode case");
994 bool noteUndefinedBehavior() {
996 return keepEvaluatingAfterUndefinedBehavior();
1001 bool keepEvaluatingAfterFailure() {
1006 case EM_PotentialConstantExpression:
1007 case EM_PotentialConstantExpressionUnevaluated:
1008 case EM_EvaluateForOverflow:
1011 case EM_ConstantExpression:
1012 case EM_ConstantExpressionUnevaluated:
1013 case EM_ConstantFold:
1014 case EM_IgnoreSideEffects:
1017 llvm_unreachable(
"Missed EvalMode case");
1030 LLVM_NODISCARD
bool noteFailure() {
1038 bool KeepGoing = keepEvaluatingAfterFailure();
1043 class ArrayInitLoopIndex {
1045 uint64_t OuterIndex;
1048 ArrayInitLoopIndex(EvalInfo &Info)
1049 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1050 Info.ArrayInitIndex = 0;
1052 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1054 operator uint64_t&() {
return Info.ArrayInitIndex; }
1059 struct FoldConstant {
1062 bool HadNoPriorDiags;
1063 EvalInfo::EvaluationMode OldMode;
1065 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1068 HadNoPriorDiags(Info.EvalStatus.Diag &&
1069 Info.EvalStatus.Diag->empty() &&
1070 !Info.EvalStatus.HasSideEffects),
1071 OldMode(Info.EvalMode) {
1073 (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
1074 Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
1075 Info.EvalMode = EvalInfo::EM_ConstantFold;
1077 void keepDiagnostics() { Enabled =
false; }
1079 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1080 !Info.EvalStatus.HasSideEffects)
1081 Info.EvalStatus.Diag->clear();
1082 Info.EvalMode = OldMode;
1088 struct IgnoreSideEffectsRAII {
1090 EvalInfo::EvaluationMode OldMode;
1091 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1092 : Info(Info), OldMode(Info.EvalMode) {
1093 if (!Info.checkingPotentialConstantExpression())
1094 Info.EvalMode = EvalInfo::EM_IgnoreSideEffects;
1097 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1102 class SpeculativeEvaluationRAII {
1103 EvalInfo *Info =
nullptr;
1105 bool OldIsSpeculativelyEvaluating;
1107 void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
1109 OldStatus = Other.OldStatus;
1110 OldIsSpeculativelyEvaluating = Other.OldIsSpeculativelyEvaluating;
1111 Other.Info =
nullptr;
1114 void maybeRestoreState() {
1118 Info->EvalStatus = OldStatus;
1119 Info->IsSpeculativelyEvaluating = OldIsSpeculativelyEvaluating;
1123 SpeculativeEvaluationRAII() =
default;
1125 SpeculativeEvaluationRAII(
1127 : Info(&Info), OldStatus(Info.EvalStatus),
1128 OldIsSpeculativelyEvaluating(Info.IsSpeculativelyEvaluating) {
1129 Info.EvalStatus.Diag = NewDiag;
1130 Info.IsSpeculativelyEvaluating =
true;
1133 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &Other) =
delete;
1134 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&Other) {
1135 moveFromAndCancel(std::move(Other));
1138 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&Other) {
1139 maybeRestoreState();
1140 moveFromAndCancel(std::move(Other));
1144 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1149 template<
bool IsFullExpression>
1152 unsigned OldStackSize;
1154 ScopeRAII(EvalInfo &Info)
1155 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1158 Info.CurrentCall->pushTempVersion();
1164 Info.CurrentCall->popTempVersion();
1167 static void cleanup(EvalInfo &Info,
unsigned OldStackSize) {
1168 unsigned NewEnd = OldStackSize;
1169 for (
unsigned I = OldStackSize, N = Info.CleanupStack.size();
1171 if (IsFullExpression && Info.CleanupStack[I].isLifetimeExtended()) {
1174 std::swap(Info.CleanupStack[I], Info.CleanupStack[NewEnd]);
1178 Info.CleanupStack[I].endLifetime();
1181 Info.CleanupStack.erase(Info.CleanupStack.begin() + NewEnd,
1182 Info.CleanupStack.end());
1185 typedef ScopeRAII<false> BlockScopeRAII;
1186 typedef ScopeRAII<true> FullExpressionRAII;
1189 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1193 if (isOnePastTheEnd()) {
1194 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1205 void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1207 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1212 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1217 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1218 Info.CCEDiag(E, diag::note_constexpr_array_index)
1220 <<
static_cast<unsigned>(getMostDerivedArraySize());
1222 Info.CCEDiag(E, diag::note_constexpr_array_index)
1227 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
1230 : Info(Info), Caller(Info.CurrentCall), Callee(Callee), This(This),
1231 Arguments(Arguments), CallLoc(CallLoc), Index(Info.NextCallIndex++) {
1232 Info.CurrentCall =
this;
1233 ++Info.CallStackDepth;
1236 CallStackFrame::~CallStackFrame() {
1237 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1238 --Info.CallStackDepth;
1239 Info.CurrentCall = Caller;
1243 bool IsLifetimeExtended) {
1244 unsigned Version = Info.CurrentCall->getTempVersion();
1246 assert(Result.
isUninit() &&
"temporary created multiple times");
1247 Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
1251 static void describeCall(CallStackFrame *Frame, raw_ostream &Out);
1253 void EvalInfo::addCallStack(
unsigned Limit) {
1255 unsigned ActiveCalls = CallStackDepth - 1;
1256 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
1257 if (Limit && Limit < ActiveCalls) {
1258 SkipStart = Limit / 2 + Limit % 2;
1259 SkipEnd = ActiveCalls - Limit / 2;
1263 unsigned CallIdx = 0;
1264 for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
1265 Frame = Frame->Caller, ++CallIdx) {
1267 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
1268 if (CallIdx == SkipStart) {
1270 addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
1271 << unsigned(ActiveCalls - Limit);
1278 if (
auto *CD = dyn_cast_or_null<CXXConstructorDecl>(Frame->Callee)) {
1279 if (CD->isInheritingConstructor()) {
1280 addDiag(Frame->CallLoc, diag::note_constexpr_inherited_ctor_call_here)
1287 llvm::raw_svector_ostream Out(Buffer);
1289 addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
1302 struct ComplexValue {
1307 APSInt IntReal, IntImag;
1308 APFloat FloatReal, FloatImag;
1310 ComplexValue() : FloatReal(APFloat::Bogus()), FloatImag(APFloat::Bogus()) {}
1312 void makeComplexFloat() { IsInt =
false; }
1313 bool isComplexFloat()
const {
return !IsInt; }
1314 APFloat &getComplexFloatReal() {
return FloatReal; }
1315 APFloat &getComplexFloatImag() {
return FloatImag; }
1317 void makeComplexInt() { IsInt =
true; }
1318 bool isComplexInt()
const {
return IsInt; }
1319 APSInt &getComplexIntReal() {
return IntReal; }
1320 APSInt &getComplexIntImag() {
return IntImag; }
1323 if (isComplexFloat())
1324 v =
APValue(FloatReal, FloatImag);
1326 v =
APValue(IntReal, IntImag);
1328 void setFrom(
const APValue &v) {
1347 bool InvalidBase : 1;
1352 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1353 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1354 bool isNullPointer()
const {
return IsNullPtr;}
1356 unsigned getLValueCallIndex()
const {
return Base.
getCallIndex(); }
1357 unsigned getLValueVersion()
const {
return Base.
getVersion(); }
1359 void moveInto(
APValue &V)
const {
1360 if (Designator.Invalid)
1363 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1364 V =
APValue(Base, Offset, Designator.Entries,
1365 Designator.IsOnePastTheEnd, IsNullPtr);
1369 assert(V.
isLValue() &&
"Setting LValue from a non-LValue?");
1372 InvalidBase =
false;
1373 Designator = SubobjectDesignator(Ctx, V);
1381 const auto *E = B.get<
const Expr *>();
1382 assert((isa<MemberExpr>(E) || tryUnwrapAllocSizeCall(E)) &&
1383 "Unexpected type of invalid base");
1389 InvalidBase = BInvalid;
1390 Designator = SubobjectDesignator(getType(B));
1394 void setNull(
QualType PointerTy, uint64_t TargetVal) {
1395 Base = (
Expr *)
nullptr;
1397 InvalidBase =
false;
1409 template <
typename GenDiagType>
1410 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1411 if (Designator.Invalid)
1415 Designator.setInvalid();
1422 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1424 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1425 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1429 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1431 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1432 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1439 return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
1440 Designator.checkSubobject(Info, E, CSK);
1443 void addDecl(EvalInfo &Info,
const Expr *E,
1444 const Decl *D,
bool Virtual =
false) {
1445 if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
1446 Designator.addDeclUnchecked(D, Virtual);
1448 void addUnsizedArray(EvalInfo &Info,
const Expr *E,
QualType ElemTy) {
1449 if (!Designator.Entries.empty()) {
1450 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1451 Designator.setInvalid();
1454 if (checkSubobject(Info, E, CSK_ArrayToPointer)) {
1455 assert(getType(Base)->isPointerType() || getType(Base)->isArrayType());
1456 Designator.FirstEntryIsAnUnsizedArray =
true;
1457 Designator.addUnsizedArrayUnchecked(ElemTy);
1461 if (checkSubobject(Info, E, CSK_ArrayToPointer))
1462 Designator.addArrayUnchecked(CAT);
1464 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1465 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1466 Designator.addComplexUnchecked(EltTy, Imag);
1468 void clearIsNullPointer() {
1471 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1472 const APSInt &Index,
CharUnits ElementSize) {
1483 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1486 if (checkNullPointer(Info, E, CSK_ArrayIndex))
1487 Designator.adjustIndex(Info, E, Index);
1488 clearIsNullPointer();
1493 clearIsNullPointer();
1500 DeclAndIsDerivedMember(Decl,
false), Path() {}
1505 return DeclAndIsDerivedMember.getPointer();
1508 bool isDerivedMember()
const {
1509 return DeclAndIsDerivedMember.getInt();
1513 return cast<CXXRecordDecl>(
1514 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1517 void moveInto(
APValue &V)
const {
1518 V =
APValue(getDecl(), isDerivedMember(), Path);
1520 void setFrom(
const APValue &V) {
1526 Path.insert(Path.end(), P.begin(), P.end());
1532 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1540 assert(!Path.empty());
1542 if (Path.size() >= 2)
1543 Expected = Path[Path.size() - 2];
1545 Expected = getContainingRecord();
1562 if (!isDerivedMember()) {
1563 Path.push_back(Derived);
1566 if (!castBack(Derived))
1569 DeclAndIsDerivedMember.setInt(
false);
1577 DeclAndIsDerivedMember.setInt(
true);
1578 if (isDerivedMember()) {
1579 Path.push_back(Base);
1582 return castBack(Base);
1587 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1588 if (!LHS.getDecl() || !RHS.getDecl())
1589 return !LHS.getDecl() && !RHS.getDecl();
1590 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1592 return LHS.Path == RHS.Path;
1598 const LValue &This,
const Expr *E,
1599 bool AllowNonLiteralTypes =
false);
1601 bool InvalidBaseOK =
false);
1603 bool InvalidBaseOK =
false);
1621 template <
class KeyTy>
1623 LValue &LV, CallStackFrame &Frame) {
1624 LV.set({Key, Frame.Info.CurrentCall->Index,
1625 Frame.Info.CurrentCall->getTempVersion()});
1626 return Frame.createTemporary(Key, IsLifetimeExtended);
1632 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1633 Int = Int.extend(Int.getBitWidth() + 1);
1634 Int.setIsSigned(
true);
1641 unsigned ArgIndex = 0;
1642 bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
1643 !isa<CXXConstructorDecl>(Frame->Callee) &&
1644 cast<CXXMethodDecl>(Frame->Callee)->isInstance();
1647 Out << *Frame->Callee <<
'(';
1649 if (Frame->This && IsMemberCall) {
1651 Frame->This->moveInto(Val);
1653 Frame->This->Designator.MostDerivedType);
1655 Out <<
"->" << *Frame->Callee <<
'(';
1656 IsMemberCall =
false;
1660 E = Frame->Callee->param_end(); I != E; ++I, ++ArgIndex) {
1661 if (ArgIndex > (
unsigned)IsMemberCall)
1665 const APValue &Arg = Frame->Arguments[ArgIndex];
1668 if (ArgIndex == 0 && IsMemberCall)
1669 Out <<
"->" << *Frame->Callee <<
'(';
1682 return Info.noteSideEffect();
1689 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1690 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1699 if (!B)
return true;
1703 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1704 return VD->hasGlobalStorage();
1706 return isa<FunctionDecl>(D);
1710 switch (E->getStmtClass()) {
1713 case Expr::CompoundLiteralExprClass: {
1717 case Expr::MaterializeTemporaryExprClass:
1720 return cast<MaterializeTemporaryExpr>(E)->getStorageDuration() ==
SD_Static;
1722 case Expr::StringLiteralClass:
1723 case Expr::PredefinedExprClass:
1724 case Expr::ObjCStringLiteralClass:
1725 case Expr::ObjCEncodeExprClass:
1726 case Expr::CXXTypeidExprClass:
1727 case Expr::CXXUuidofExprClass:
1729 case Expr::CallExprClass:
1732 case Expr::AddrLabelExprClass:
1736 case Expr::BlockExprClass:
1737 return !cast<BlockExpr>(E)->getBlockDecl()->hasCaptures();
1738 case Expr::ImplicitValueInitExprClass:
1750 return LVal.Base.dyn_cast<
const ValueDecl*>();
1754 if (Value.getLValueCallIndex())
1756 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1757 return E && !isa<MaterializeTemporaryExpr>(E);
1762 return Decl && Decl->
isWeak();
1767 if (Decl && isa<VarDecl>(Decl)) {
1777 if (!A.getLValueBase())
1778 return !B.getLValueBase();
1779 if (!B.getLValueBase())
1782 if (A.getLValueBase().getOpaqueValue() !=
1783 B.getLValueBase().getOpaqueValue()) {
1793 (A.getLValueCallIndex() == B.getLValueCallIndex() &&
1794 A.getLValueVersion() == B.getLValueVersion());
1798 assert(Base &&
"no location for a null lvalue");
1801 Info.Note(VD->
getLocation(), diag::note_declared_at);
1804 diag::note_constexpr_temporary_here);
1816 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
1822 if (Info.getLangOpts().CPlusPlus11) {
1824 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
1825 << IsReferenceType << !Designator.Entries.empty()
1834 assert((Info.checkingPotentialConstantExpression() ||
1835 LVal.getLValueCallIndex() == 0) &&
1836 "have call index for global lvalue");
1839 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
1841 if (Var->getTLSKind())
1848 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
1860 FD->hasAttr<DLLImportAttr>())
1867 if (!IsReferenceType)
1878 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
1880 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
1881 << !Designator.Entries.empty() << !!VD << VD;
1896 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
1900 !FD->hasAttr<DLLImportAttr>();
1906 const LValue *This =
nullptr) {
1923 if (This && Info.EvaluatingDecl == This->getLValueBase())
1927 if (Info.getLangOpts().CPlusPlus11)
1928 Info.FFDiag(E, diag::note_constexpr_nonliteral)
1931 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1943 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
1951 Type = AT->getValueType();
1975 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
1976 unsigned BaseIndex = 0;
1984 for (
const auto *I : RD->
fields()) {
1985 if (I->isUnnamedBitfield())
1997 LVal.setFrom(Info.Ctx, Value);
2020 return !Decl || !Decl->
isWeak();
2028 Result = Val.
getInt().getBoolValue();
2054 llvm_unreachable(
"unknown APValue kind");
2059 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2066 template<
typename T>
2068 const T &SrcValue,
QualType DestType) {
2069 Info.CCEDiag(E, diag::note_constexpr_overflow)
2070 << SrcValue << DestType;
2071 return Info.noteUndefinedBehavior();
2075 QualType SrcType,
const APFloat &Value,
2076 QualType DestType, APSInt &Result) {
2077 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2081 Result = APSInt(DestWidth, !DestSigned);
2083 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2084 & APFloat::opInvalidOp)
2094 if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
2095 APFloat::rmNearestTiesToEven, &ignored)
2096 & APFloat::opOverflow)
2103 const APSInt &Value) {
2104 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2107 APSInt Result = Value.extOrTrunc(DestWidth);
2110 Result = Value.getBoolValue();
2115 QualType SrcType,
const APSInt &Value,
2116 QualType DestType, APFloat &Result) {
2117 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2118 if (Result.convertFromAPInt(Value, Value.isSigned(),
2119 APFloat::rmNearestTiesToEven)
2120 & APFloat::opOverflow)
2127 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2129 if (!Value.
isInt()) {
2133 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
2138 APSInt &Int = Value.
getInt();
2139 unsigned OldBitWidth = Int.getBitWidth();
2141 if (NewBitWidth < OldBitWidth)
2142 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2156 Res = SVal.
getFloat().bitcastToAPInt();
2161 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
2163 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
2164 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
2165 Res = llvm::APInt::getNullValue(VecSize);
2168 llvm::APInt EltAsInt;
2172 EltAsInt = Elt.
getFloat().bitcastToAPInt();
2176 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2179 unsigned BaseEltSize = EltAsInt.getBitWidth();
2181 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(i*EltSize+BaseEltSize);
2183 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(i*EltSize);
2189 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2196 template<
typename Operation>
2198 const APSInt &LHS,
const APSInt &RHS,
2199 unsigned BitWidth, Operation Op,
2201 if (LHS.isUnsigned()) {
2202 Result = Op(LHS, RHS);
2206 APSInt
Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2207 Result = Value.trunc(LHS.getBitWidth());
2208 if (Result.extend(BitWidth) !=
Value) {
2209 if (Info.checkingForOverflow())
2210 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2211 diag::warn_integer_constant_overflow)
2212 << Result.toString(10) << E->
getType();
2229 std::multiplies<APSInt>(), Result);
2232 std::plus<APSInt>(), Result);
2235 std::minus<APSInt>(), Result);
2236 case BO_And: Result = LHS & RHS;
return true;
2237 case BO_Xor: Result = LHS ^ RHS;
return true;
2238 case BO_Or: Result = LHS | RHS;
return true;
2242 Info.FFDiag(E, diag::note_expr_divide_by_zero);
2245 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2248 if (RHS.isNegative() && RHS.isAllOnesValue() &&
2249 LHS.isSigned() && LHS.isMinSignedValue())
2250 return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
2254 if (Info.getLangOpts().OpenCL)
2256 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2257 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2259 else if (RHS.isSigned() && RHS.isNegative()) {
2262 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2269 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2271 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2272 << RHS << E->
getType() << LHS.getBitWidth();
2273 }
else if (LHS.isSigned()) {
2276 if (LHS.isNegative())
2277 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2278 else if (LHS.countLeadingZeros() < SA)
2279 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2285 if (Info.getLangOpts().OpenCL)
2287 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2288 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2290 else if (RHS.isSigned() && RHS.isNegative()) {
2293 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2300 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2302 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2303 << RHS << E->
getType() << LHS.getBitWidth();
2308 case BO_LT: Result = LHS < RHS;
return true;
2309 case BO_GT: Result = LHS > RHS;
return true;
2310 case BO_LE: Result = LHS <= RHS;
return true;
2311 case BO_GE: Result = LHS >= RHS;
return true;
2312 case BO_EQ: Result = LHS == RHS;
return true;
2313 case BO_NE: Result = LHS != RHS;
return true;
2315 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2322 const APFloat &RHS) {
2328 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
2331 LHS.add(RHS, APFloat::rmNearestTiesToEven);
2334 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
2337 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
2341 if (LHS.isInfinity() || LHS.isNaN()) {
2342 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2343 return Info.noteUndefinedBehavior();
2352 unsigned TruncatedElements) {
2353 SubobjectDesignator &D = Result.Designator;
2356 if (TruncatedElements == D.Entries.size())
2358 assert(TruncatedElements >= D.MostDerivedPathLength &&
2359 "not casting to a derived class");
2360 if (!Result.checkSubobject(Info, E, CSK_Derived))
2365 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
2369 if (isVirtualBaseClass(D.Entries[I]))
2375 D.Entries.resize(TruncatedElements);
2385 RL = &Info.Ctx.getASTRecordLayout(Derived);
2388 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
2389 Obj.addDecl(Info, E, Base,
false);
2401 SubobjectDesignator &D = Obj.Designator;
2406 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
2412 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
2414 Obj.addDecl(Info, E, BaseDecl,
true);
2422 PathI != PathE; ++PathI) {
2426 Type = (*PathI)->getType();
2438 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
2442 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
2443 LVal.addDecl(Info, E, FD);
2451 for (
const auto *
C : IFD->
chain())
2479 Size = Info.Ctx.getTypeSizeInChars(Type);
2491 APSInt Adjustment) {
2496 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
2502 int64_t Adjustment) {
2504 APSInt::get(Adjustment));
2519 LVal.Offset += SizeOfComponent;
2521 LVal.addComplex(Info, E, EltTy, Imag);
2538 const VarDecl *VD, CallStackFrame *Frame,
2539 APValue *&Result,
const LValue *LVal) {
2543 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
2546 if (Info.checkingPotentialConstantExpression())
2548 if (!Frame || !Frame->Arguments) {
2549 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2552 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
2558 Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion())
2559 : Frame->getCurrentTemporary(VD);
2567 "missing value for local variable");
2568 if (Info.checkingPotentialConstantExpression())
2572 diag::note_unimplemented_constexpr_lambda_feature_ast)
2573 <<
"captures not currently allowed";
2584 if (!Info.checkingPotentialConstantExpression())
2585 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2591 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
2592 Result = Info.EvaluatingDeclValue;
2599 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2607 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant,
2608 Notes.size() + 1) << VD;
2609 Info.Note(VD->
getLocation(), diag::note_declared_at);
2610 Info.addNotes(Notes);
2613 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2614 Notes.size() + 1) << VD;
2615 Info.Note(VD->
getLocation(), diag::note_declared_at);
2616 Info.addNotes(Notes);
2635 E = Derived->
bases_end(); I != E; ++I, ++Index) {
2636 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2640 llvm_unreachable(
"base class missing from derived class's bases list");
2647 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
2649 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
2650 assert(Index <= Str.size() &&
"Index too large");
2651 return APSInt::getUnsigned(Str.c_str()[Index]);
2654 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2655 Lit = PE->getFunctionName();
2658 Info.Ctx.getAsConstantArrayType(S->
getType());
2659 assert(CAT &&
"string literal isn't an array");
2660 QualType CharType = CAT->getElementType();
2661 assert(CharType->
isIntegerType() &&
"unexpected character type");
2665 if (Index < S->getLength())
2675 Info.Ctx.getAsConstantArrayType(S->
getType());
2676 assert(CAT &&
"string literal isn't an array");
2677 QualType CharType = CAT->getElementType();
2678 assert(CharType->
isIntegerType() &&
"unexpected character type");
2680 unsigned Elts = CAT->getSize().getZExtValue();
2696 assert(Index < Size);
2700 unsigned NewElts =
std::max(Index+1, OldElts * 2);
2705 for (
unsigned I = 0; I != OldElts; ++I)
2707 for (
unsigned I = OldElts; I != NewElts; ++I)
2711 Array.
swap(NewValue);
2726 for (
auto *Field : RD->
fields())
2730 for (
auto &BaseSpec : RD->
bases())
2748 for (
auto *Field : RD->
fields()) {
2753 if (Field->isMutable() &&
2755 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field;
2756 Info.Note(Field->getLocation(), diag::note_declared_at);
2764 for (
auto &BaseSpec : RD->
bases())
2775 struct CompleteObject {
2780 bool LifetimeStartedInEvaluation;
2782 CompleteObject() :
Value(
nullptr) {}
2784 bool LifetimeStartedInEvaluation)
2785 :
Value(Value), Type(Type),
2786 LifetimeStartedInEvaluation(LifetimeStartedInEvaluation) {
2787 assert(Value &&
"missing value for complete object");
2790 explicit operator bool()
const {
return Value; }
2795 template<
typename Sub
objectHandler>
2796 typename SubobjectHandler::result_type
2798 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
2801 return handler.failed();
2802 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
2803 if (Info.getLangOpts().CPlusPlus11)
2804 Info.FFDiag(E, Sub.isOnePastTheEnd()
2805 ? diag::note_constexpr_access_past_end
2806 : diag::note_constexpr_access_unsized_array)
2807 << handler.AccessKind;
2810 return handler.failed();
2816 const bool MayReadMutableMembers =
2817 Obj.LifetimeStartedInEvaluation && Info.getLangOpts().CPlusPlus14;
2820 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
2822 if (!Info.checkingPotentialConstantExpression())
2823 Info.FFDiag(E, diag::note_constexpr_access_uninit) << handler.AccessKind;
2824 return handler.failed();
2834 return handler.failed();
2836 if (!handler.found(*O, ObjType))
2840 if (handler.AccessKind !=
AK_Read &&
2848 LastField =
nullptr;
2852 assert(CAT &&
"vla in literal type?");
2853 uint64_t Index = Sub.Entries[I].ArrayIndex;
2854 if (CAT->
getSize().ule(Index)) {
2857 if (Info.getLangOpts().CPlusPlus11)
2858 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2859 << handler.AccessKind;
2862 return handler.failed();
2870 assert(I == N - 1 &&
"extracting subobject of character?");
2872 if (handler.AccessKind !=
AK_Read)
2876 return handler.foundString(*O, ObjType, Index);
2881 else if (handler.AccessKind !=
AK_Read) {
2888 uint64_t Index = Sub.Entries[I].ArrayIndex;
2890 if (Info.getLangOpts().CPlusPlus11)
2891 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2892 << handler.AccessKind;
2895 return handler.failed();
2900 if (WasConstQualified)
2903 assert(I == N - 1 &&
"extracting subobject of scalar?");
2912 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
2916 if (Field->isMutable() && handler.AccessKind ==
AK_Read &&
2917 !MayReadMutableMembers) {
2918 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1)
2920 Info.Note(Field->getLocation(), diag::note_declared_at);
2921 return handler.failed();
2930 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
2931 << handler.AccessKind << Field << !UnionField << UnionField;
2932 return handler.failed();
2939 ObjType = Field->getType();
2940 if (WasConstQualified && !Field->isMutable())
2944 if (Info.getLangOpts().CPlusPlus) {
2946 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
2947 << handler.AccessKind << 2 << Field;
2948 Info.Note(Field->getLocation(), diag::note_declared_at);
2950 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2952 return handler.failed();
2963 ObjType = Info.Ctx.getRecordType(Base);
2964 if (WasConstQualified)
2971 struct ExtractSubobjectHandler {
2977 typedef bool result_type;
2978 bool failed() {
return false; }
2983 bool found(APSInt &Value,
QualType SubobjType) {
2987 bool found(APFloat &Value,
QualType SubobjType) {
2991 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3003 const CompleteObject &Obj,
3004 const SubobjectDesignator &Sub,
3006 ExtractSubobjectHandler Handler = { Info, Result };
3011 struct ModifySubobjectHandler {
3016 typedef bool result_type;
3022 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3028 bool failed() {
return false; }
3030 if (!checkConst(SubobjType))
3033 Subobj.
swap(NewVal);
3036 bool found(APSInt &Value,
QualType SubobjType) {
3037 if (!checkConst(SubobjType))
3039 if (!NewVal.
isInt()) {
3047 bool found(APFloat &Value,
QualType SubobjType) {
3048 if (!checkConst(SubobjType))
3053 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3054 llvm_unreachable(
"shouldn't encounter string elements with ExpandArrays");
3063 const CompleteObject &Obj,
3064 const SubobjectDesignator &Sub,
3066 ModifySubobjectHandler Handler = { Info, NewVal, E };
3073 const SubobjectDesignator &A,
3074 const SubobjectDesignator &B,
3075 bool &WasArrayIndex) {
3076 unsigned I = 0, N =
std::min(A.Entries.size(), B.Entries.size());
3077 for (; I != N; ++I) {
3081 if (A.Entries[I].ArrayIndex != B.Entries[I].ArrayIndex) {
3082 WasArrayIndex =
true;
3090 if (A.Entries[I].BaseOrMember != B.Entries[I].BaseOrMember) {
3091 WasArrayIndex =
false;
3094 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
3096 ObjType = FD->getType();
3102 WasArrayIndex =
false;
3109 const SubobjectDesignator &A,
3110 const SubobjectDesignator &B) {
3111 if (A.Entries.size() != B.Entries.size())
3114 bool IsArray = A.MostDerivedIsArrayElement;
3115 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
3124 return CommonLength >= A.Entries.size() - IsArray;
3132 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
3133 return CompleteObject();
3136 CallStackFrame *Frame =
nullptr;
3137 if (LVal.getLValueCallIndex()) {
3138 Frame = Info.getCallFrame(LVal.getLValueCallIndex());
3140 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
3141 << AK << LVal.Base.is<
const ValueDecl*>();
3143 return CompleteObject();
3152 if (Info.getLangOpts().CPlusPlus)
3153 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
3157 return CompleteObject();
3162 QualType BaseType = getType(LVal.Base);
3163 bool LifetimeStartedInEvaluation = Frame;
3180 return CompleteObject();
3185 if (Info.getLangOpts().CPlusPlus) {
3186 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3188 Info.Note(VD->getLocation(), diag::note_declared_at);
3192 return CompleteObject();
3198 if (Info.getLangOpts().CPlusPlus14 &&
3199 VD == Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()) {
3205 Info.FFDiag(E, diag::note_constexpr_modify_global);
3206 return CompleteObject();
3212 (Info.getLangOpts().OpenCL &&
3214 if (Info.getLangOpts().CPlusPlus) {
3215 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
3216 Info.Note(VD->
getLocation(), diag::note_declared_at);
3220 return CompleteObject();
3226 if (Info.getLangOpts().CPlusPlus11) {
3227 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3228 Info.Note(VD->
getLocation(), diag::note_declared_at);
3233 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD;
3237 if (Info.checkingPotentialConstantExpression() &&
3241 }
else if (Info.getLangOpts().CPlusPlus11) {
3242 Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3243 Info.Note(VD->
getLocation(), diag::note_declared_at);
3247 return CompleteObject();
3252 return CompleteObject();
3254 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3258 dyn_cast<MaterializeTemporaryExpr>(Base)) {
3259 assert(MTE->getStorageDuration() ==
SD_Static &&
3260 "should have a frame for a non-global materialized temporary");
3277 const ValueDecl *ED = MTE->getExtendingDecl();
3280 !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) {
3281 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
3282 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
3283 return CompleteObject();
3286 BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE,
false);
3287 assert(BaseVal &&
"got reference to unevaluated temporary");
3288 LifetimeStartedInEvaluation =
true;
3291 return CompleteObject();
3294 BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion());
3295 assert(BaseVal &&
"missing value for temporary");
3300 if (Info.getLangOpts().CPlusPlus) {
3301 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3303 Info.Note(Base->
getExprLoc(), diag::note_constexpr_temporary_here);
3307 return CompleteObject();
3314 if (Info.isEvaluatingConstructor(LVal.getLValueBase(),
3315 LVal.getLValueCallIndex(),
3316 LVal.getLValueVersion())) {
3317 BaseType = Info.Ctx.getCanonicalType(BaseType);
3319 LifetimeStartedInEvaluation =
true;
3327 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
3328 Info.EvalStatus.HasSideEffects) ||
3329 (AK !=
AK_Read && Info.IsSpeculativelyEvaluating))
3330 return CompleteObject();
3332 return CompleteObject(BaseVal, BaseType, LifetimeStartedInEvaluation);
3348 const LValue &LVal,
APValue &RVal) {
3349 if (LVal.Designator.Invalid)
3353 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3364 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
3366 CompleteObject LitObj(&Lit, Base->
getType(),
false);
3368 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
3373 CompleteObject StrObj(&Str, Base->
getType(),
false);
3385 if (LVal.Designator.Invalid)
3388 if (!Info.getLangOpts().CPlusPlus14) {
3398 struct CompoundAssignSubobjectHandler {
3407 typedef bool result_type;
3412 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3418 bool failed() {
return false; }
3422 return found(Subobj.
getInt(), SubobjType);
3424 return found(Subobj.
getFloat(), SubobjType);
3431 return foundPointer(Subobj, SubobjType);
3438 bool found(APSInt &Value,
QualType SubobjType) {
3439 if (!checkConst(SubobjType))
3457 APFloat FValue(0.0);
3468 bool found(APFloat &Value,
QualType SubobjType) {
3469 return checkConst(SubobjType) &&
3476 if (!checkConst(SubobjType))
3484 (Opcode != BO_Add && Opcode != BO_Sub)) {
3490 if (Opcode == BO_Sub)
3494 LVal.setFrom(Info.Ctx, Subobj);
3497 LVal.moveInto(Subobj);
3500 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3501 llvm_unreachable(
"shouldn't encounter string elements here");
3510 EvalInfo &Info,
const Expr *E,
3513 if (LVal.Designator.Invalid)
3516 if (!Info.getLangOpts().CPlusPlus14) {
3522 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
3524 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3528 struct IncDecSubobjectHandler {
3534 typedef bool result_type;
3539 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3545 bool failed() {
return false; }
3556 return found(Subobj.
getInt(), SubobjType);
3558 return found(Subobj.
getFloat(), SubobjType);
3568 return foundPointer(Subobj, SubobjType);
3575 bool found(APSInt &Value,
QualType SubobjType) {
3576 if (!checkConst(SubobjType))
3586 if (Old) *Old =
APValue(Value);
3598 bool WasNegative = Value.isNegative();
3602 if (!WasNegative && Value.isNegative() && E->
canOverflow()) {
3603 APSInt ActualValue(Value,
true);
3609 if (WasNegative && !Value.isNegative() && E->
canOverflow()) {
3610 unsigned BitWidth = Value.getBitWidth();
3611 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
3612 ActualValue.setBit(BitWidth);
3618 bool found(APFloat &Value,
QualType SubobjType) {
3619 if (!checkConst(SubobjType))
3622 if (Old) *Old =
APValue(Value);
3624 APFloat One(Value.getSemantics(), 1);
3626 Value.add(One, APFloat::rmNearestTiesToEven);
3628 Value.subtract(One, APFloat::rmNearestTiesToEven);
3632 if (!checkConst(SubobjType))
3644 LVal.setFrom(Info.Ctx, Subobj);
3648 LVal.moveInto(Subobj);
3651 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3652 llvm_unreachable(
"shouldn't encounter string elements here");
3660 if (LVal.Designator.Invalid)
3663 if (!Info.getLangOpts().CPlusPlus14) {
3670 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(E), AK, Old};
3671 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3686 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
3705 bool IncludeMember =
true) {
3712 if (!MemPtr.getDecl()) {
3718 if (MemPtr.isDerivedMember()) {
3722 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
3723 LV.Designator.Entries.size()) {
3727 unsigned PathLengthToMember =
3728 LV.Designator.Entries.size() - MemPtr.Path.size();
3729 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
3731 LV.Designator.Entries[PathLengthToMember + I]);
3741 PathLengthToMember))
3743 }
else if (!MemPtr.Path.empty()) {
3745 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
3746 MemPtr.Path.size() + IncludeMember);
3752 assert(RD &&
"member pointer access on non-class-type expression");
3754 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
3762 MemPtr.getContainingRecord()))
3767 if (IncludeMember) {
3768 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
3772 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
3776 llvm_unreachable(
"can't construct reference to bound member function");
3780 return MemPtr.getDecl();
3786 bool IncludeMember =
true) {
3790 if (Info.noteFailure()) {
3798 BO->
getRHS(), IncludeMember);
3805 SubobjectDesignator &D = Result.Designator;
3806 if (D.Invalid || !Result.checkNullPointer(Info, E, CSK_Derived))
3814 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
3815 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3816 << D.MostDerivedType << TargetQT;
3822 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
3825 if (NewEntriesSize == D.MostDerivedPathLength)
3826 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
3828 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
3830 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3831 << D.MostDerivedType << TargetQT;
3866 Info.FFDiag(VD->
getBeginLoc(), diag::note_constexpr_uninitialized)
3888 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
3892 for (
auto *BD : DD->bindings())
3893 if (
auto *VD = BD->getHoldingVar())
3902 const Expr *Cond,
bool &Result) {
3903 FullExpressionRAII
Scope(Info);
3919 struct TempVersionRAII {
3920 CallStackFrame &Frame;
3922 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
3923 Frame.pushTempVersion();
3926 ~TempVersionRAII() {
3927 Frame.popTempVersion();
3941 BlockScopeRAII
Scope(Info);
3944 return ESR_Succeeded;
3947 return ESR_Continue;
3950 case ESR_CaseNotFound:
3953 llvm_unreachable(
"Invalid EvalStmtResult!");
3959 BlockScopeRAII
Scope(Info);
3964 FullExpressionRAII Scope(Info);
3967 if (ESR != ESR_Succeeded)
3982 if (isa<DefaultStmt>(SC)) {
3987 const CaseStmt *CS = cast<CaseStmt>(SC);
3991 if (LHS <= Value && Value <= RHS) {
3998 return ESR_Succeeded;
4003 return ESR_Succeeded;
4009 case ESR_CaseNotFound:
4013 diag::note_constexpr_stmt_expr_unsupported);
4016 llvm_unreachable(
"Invalid EvalStmtResult!");
4022 if (!Info.nextStep(S))
4033 case Stmt::CompoundStmtClass:
4037 case Stmt::LabelStmtClass:
4038 case Stmt::AttributedStmtClass:
4039 case Stmt::DoStmtClass:
4042 case Stmt::CaseStmtClass:
4043 case Stmt::DefaultStmtClass:
4048 case Stmt::IfStmtClass: {
4051 const IfStmt *IS = cast<IfStmt>(S);
4055 BlockScopeRAII
Scope(Info);
4058 if (ESR != ESR_CaseNotFound || !IS->
getElse())
4063 case Stmt::WhileStmtClass: {
4066 if (ESR != ESR_Continue)
4071 case Stmt::ForStmtClass: {
4072 const ForStmt *FS = cast<ForStmt>(S);
4075 if (ESR != ESR_Continue)
4078 FullExpressionRAII IncScope(Info);
4085 case Stmt::DeclStmtClass:
4089 return ESR_CaseNotFound;
4095 if (
const Expr *E = dyn_cast<Expr>(S)) {
4098 FullExpressionRAII
Scope(Info);
4101 return ESR_Succeeded;
4107 case Stmt::NullStmtClass:
4108 return ESR_Succeeded;
4110 case Stmt::DeclStmtClass: {
4111 const DeclStmt *DS = cast<DeclStmt>(S);
4112 for (
const auto *DclIt : DS->
decls()) {
4116 FullExpressionRAII
Scope(Info);
4120 return ESR_Succeeded;
4123 case Stmt::ReturnStmtClass: {
4124 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
4125 FullExpressionRAII
Scope(Info);
4128 ? EvaluateInPlace(Result.Value, Info, *Result.Slot, RetExpr)
4129 : Evaluate(Result.Value, Info, RetExpr)))
4131 return ESR_Returned;
4134 case Stmt::CompoundStmtClass: {
4135 BlockScopeRAII
Scope(Info);
4138 for (
const auto *BI : CS->
body()) {
4140 if (ESR == ESR_Succeeded)
4142 else if (ESR != ESR_CaseNotFound)
4145 return Case ? ESR_CaseNotFound : ESR_Succeeded;
4148 case Stmt::IfStmtClass: {
4149 const IfStmt *IS = cast<IfStmt>(S);
4152 BlockScopeRAII
Scope(Info);
4155 if (ESR != ESR_Succeeded)
4164 if (ESR != ESR_Succeeded)
4167 return ESR_Succeeded;
4170 case Stmt::WhileStmtClass: {
4171 const WhileStmt *WS = cast<WhileStmt>(S);
4173 BlockScopeRAII
Scope(Info);
4182 if (ESR != ESR_Continue)
4185 return ESR_Succeeded;
4188 case Stmt::DoStmtClass: {
4189 const DoStmt *DS = cast<DoStmt>(S);
4193 if (ESR != ESR_Continue)
4197 FullExpressionRAII CondScope(Info);
4201 return ESR_Succeeded;
4204 case Stmt::ForStmtClass: {
4205 const ForStmt *FS = cast<ForStmt>(S);
4206 BlockScopeRAII
Scope(Info);
4209 if (ESR != ESR_Succeeded)
4213 BlockScopeRAII Scope(Info);
4214 bool Continue =
true;
4222 if (ESR != ESR_Continue)
4226 FullExpressionRAII IncScope(Info);
4231 return ESR_Succeeded;
4234 case Stmt::CXXForRangeStmtClass: {
4236 BlockScopeRAII
Scope(Info);
4241 if (ESR != ESR_Succeeded)
4247 if (ESR != ESR_Succeeded)
4252 if (ESR != ESR_Succeeded)
4255 if (ESR != ESR_Succeeded)
4261 bool Continue =
true;
4262 FullExpressionRAII CondExpr(Info);
4270 BlockScopeRAII InnerScope(Info);
4272 if (ESR != ESR_Succeeded)
4277 if (ESR != ESR_Continue)
4285 return ESR_Succeeded;
4288 case Stmt::SwitchStmtClass:
4291 case Stmt::ContinueStmtClass:
4292 return ESR_Continue;
4294 case Stmt::BreakStmtClass:
4297 case Stmt::LabelStmtClass:
4298 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
4300 case Stmt::AttributedStmtClass:
4303 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
4306 case Stmt::CaseStmtClass:
4307 case Stmt::DefaultStmtClass:
4308 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
4309 case Stmt::CXXTryStmtClass:
4311 return EvaluateStmt(Result, Info, cast<CXXTryStmt>(S)->getTryBlock(), Case);
4321 bool IsValueInitialization) {
4328 if (!CD->
isConstexpr() && !IsValueInitialization) {
4329 if (Info.getLangOpts().CPlusPlus11) {
4332 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
4334 Info.Note(CD->
getLocation(), diag::note_declared_at);
4336 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
4350 if (Info.checkingPotentialConstantExpression() && !Definition &&
4358 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4367 if (Info.getLangOpts().CPlusPlus11) {
4368 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
4373 if (CD && CD->isInheritingConstructor()) {
4375 if (!Inherited->isConstexpr())
4376 DiagDecl = CD = Inherited;
4382 if (CD && CD->isInheritingConstructor())
4383 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
4384 << CD->getInheritedConstructor().getConstructor()->getParent();
4386 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
4388 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
4390 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4400 for (
auto *FD : RD->
fields()) {
4401 if (FD->isUnnamedBitfield())
4405 for (
auto &Base : RD->
bases())
4406 if (
hasFields(Base.getType()->getAsCXXRecordDecl()))
4418 bool Success =
true;
4421 if (!
Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
4424 if (!Info.noteFailure())
4436 EvalInfo &Info,
APValue &Result,
4437 const LValue *ResultSlot) {
4438 ArgVector ArgValues(Args.size());
4442 if (!Info.CheckCallLimit(CallLoc))
4445 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
4454 if (MD && MD->isDefaulted() &&
4455 (MD->getParent()->isUnion() ||
4456 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
4458 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
4460 RHS.setFrom(Info.Ctx, ArgValues[0]);
4468 This->moveInto(Result);
4477 if (!Info.checkingPotentialConstantExpression())
4478 MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
4479 Frame.LambdaThisCaptureField);
4484 if (ESR == ESR_Succeeded) {
4487 Info.FFDiag(Callee->
getEndLoc(), diag::note_constexpr_no_return);
4489 return ESR == ESR_Returned;
4496 EvalInfo &Info,
APValue &Result) {
4498 if (!Info.CheckCallLimit(CallLoc))
4503 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
4507 EvalInfo::EvaluatingConstructorRAII EvalObj(
4508 Info, {This.getLValueBase(),
4509 {This.getLValueCallIndex(), This.getLValueVersion()}});
4510 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
4521 FullExpressionRAII InitScope(Info);
4540 RHS.setFrom(Info.Ctx, ArgValues[0]);
4555 BlockScopeRAII LifetimeExtendedScope(Info);
4557 bool Success =
true;
4558 unsigned BasesSeen = 0;
4562 for (
const auto *I : Definition->
inits()) {
4563 LValue Subobject = This;
4564 LValue SubobjectParent = This;
4569 if (I->isBaseInitializer()) {
4570 QualType BaseType(I->getBaseClass(), 0);
4574 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
4575 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
4576 "base class initializers not in expected order");
4580 BaseType->getAsCXXRecordDecl(), &Layout))
4583 }
else if ((FD = I->getMember())) {
4595 auto IndirectFieldChain = IFD->chain();
4596 for (
auto *
C : IndirectFieldChain) {
4597 FD = cast<FieldDecl>(
C);
4614 if (
C == IndirectFieldChain.back())
4615 SubobjectParent = Subobject;
4624 llvm_unreachable(
"unknown base initializer kind");
4630 const Expr *Init = I->getInit();
4631 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
4632 isa<CXXDefaultInitExpr>(Init));
4633 FullExpressionRAII InitScope(Info);
4639 if (!Info.noteFailure())
4652 EvalInfo &Info,
APValue &Result) {
4653 ArgVector ArgValues(Args.size());
4666 template <
class Derived>
4667 class ExprEvaluatorBase
4670 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
4671 bool DerivedSuccess(
const APValue &V,
const Expr *E) {
4672 return getDerived().Success(V, E);
4674 bool DerivedZeroInitialization(
const Expr *E) {
4675 return getDerived().ZeroInitialization(E);
4681 template<
typename ConditionalOperator>
4683 assert(Info.checkingPotentialConstantExpression());
4688 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4695 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4702 Error(E, diag::note_constexpr_conditional_never_const);
4706 template<
typename ConditionalOperator>
4710 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
4711 CheckPotentialConstantConditional(E);
4714 if (Info.noteFailure()) {
4722 return StmtVisitorTy::Visit(EvalExpr);
4728 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
4731 return Info.CCEDiag(E, D);
4734 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
4737 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
4739 EvalInfo &getEvalInfo() {
return Info; }
4748 return Error(E, diag::note_invalid_subexpr_in_const_expr);
4751 bool VisitStmt(
const Stmt *) {
4752 llvm_unreachable(
"Expression evaluator should not be called on stmts");
4754 bool VisitExpr(
const Expr *E) {
4759 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4761 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4763 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4765 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4773 TempVersionRAII RAII(*Info.CurrentCall);
4774 return StmtVisitorTy::Visit(E->
getExpr());
4777 TempVersionRAII RAII(*Info.CurrentCall);
4781 return StmtVisitorTy::Visit(E->
getExpr());
4786 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4789 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
4790 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4793 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
4794 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4803 VisitIgnoredValue(E->
getLHS());
4804 return StmtVisitorTy::Visit(E->
getRHS());
4814 return DerivedSuccess(Result, E);
4826 return HandleConditionalOperator(E);
4830 bool IsBcpCall =
false;
4837 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
4842 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
4845 FoldConstant Fold(Info, IsBcpCall);
4846 if (!HandleConditionalOperator(E)) {
4847 Fold.keepDiagnostics();
4855 if (
APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
4856 return DerivedSuccess(*Value, E);
4862 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
4865 return StmtVisitorTy::Visit(Source);
4868 bool VisitCallExpr(
const CallExpr *E) {
4870 if (!handleCallExpr(E, Result,
nullptr))
4872 return DerivedSuccess(Result, E);
4876 const LValue *ResultSlot) {
4881 LValue *This =
nullptr, ThisVal;
4883 bool HasQualifier =
false;
4888 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
4892 Member = ME->getMemberDecl();
4894 HasQualifier = ME->hasQualifier();
4895 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
4898 if (!Member)
return false;
4901 return Error(Callee);
4905 return Error(Callee);
4911 if (!Call.getLValueOffset().isZero())
4912 return Error(Callee);
4913 FD = dyn_cast_or_null<FunctionDecl>(
4914 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
4916 return Error(Callee);
4919 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
4937 Args = Args.slice(1);
4946 "Number of captures must be zero for conversion to function-ptr");
4957 "A generic lambda's static-invoker function must be a " 4958 "template specialization");
4961 LambdaCallOp->getDescribedFunctionTemplate();
4962 void *InsertPos =
nullptr;
4965 assert(CorrespondingCallOpSpecialization &&
4966 "We must always have a function call operator specialization " 4967 "that corresponds to our static invoker specialization");
4968 FD = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
4977 if (This && !This->checkSubobject(Info, E, CSK_This))
4982 if (This && !HasQualifier &&
4983 isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
4984 return Error(E, diag::note_constexpr_virtual_call);
5002 return DerivedZeroInitialization(E);
5004 return StmtVisitorTy::Visit(E->
getInit(0));
5008 return DerivedZeroInitialization(E);
5011 return DerivedZeroInitialization(E);
5014 return DerivedZeroInitialization(E);
5019 assert(!E->
isArrow() &&
"missing call to bound member function?");
5028 if (!FD)
return Error(E);
5033 CompleteObject Obj(&Val, BaseTy,
true);
5035 Designator.addDeclUnchecked(FD);
5039 DerivedSuccess(Result, E);
5042 bool VisitCastExpr(
const CastExpr *E) {
5047 case CK_AtomicToNonAtomic: {
5054 return DerivedSuccess(AtomicVal, E);
5058 case CK_UserDefinedConversion:
5059 return StmtVisitorTy::Visit(E->
getSubExpr());
5061 case CK_LValueToRValue: {
5070 return DerivedSuccess(RVal, E);
5078 return VisitUnaryPostIncDec(UO);
5081 return VisitUnaryPostIncDec(UO);
5084 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5094 return DerivedSuccess(RVal, UO);
5097 bool VisitStmtExpr(
const StmtExpr *E) {
5100 if (Info.checkingForOverflow())
5103 BlockScopeRAII
Scope(Info);
5112 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
5114 Info.FFDiag((*BI)->getBeginLoc(),
5115 diag::note_constexpr_stmt_expr_unsupported);
5118 return this->Visit(FinalExpr);
5122 StmtResult Result = { ReturnValue,
nullptr };
5124 if (ESR != ESR_Succeeded) {
5128 if (ESR != ESR_Failed)
5129 Info.FFDiag((*BI)->getBeginLoc(),
5130 diag::note_constexpr_stmt_expr_unsupported);
5135 llvm_unreachable(
"Return from function from the loop above.");
5139 void VisitIgnoredValue(
const Expr *E) {
5144 void VisitIgnoredBaseExpression(
const Expr *E) {
5147 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
5149 VisitIgnoredValue(E);
5159 template<
class Derived>
5160 class LValueExprEvaluatorBase
5161 :
public ExprEvaluatorBase<Derived> {
5165 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
5166 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
5173 bool evaluatePointer(
const Expr *E, LValue &Result) {
5178 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
5179 : ExprEvaluatorBaseTy(Info),
Result(Result),
5180 InvalidBaseOK(InvalidBaseOK) {}
5183 Result.setFrom(this->Info.Ctx, V);
5199 EvalOK = this->Visit(E->
getBase());
5205 Result.setInvalid(E);
5212 FD->
getParent()->getCanonicalDecl() &&
"record / field mismatch");
5220 return this->
Error(E);
5227 return Success(RefValue, E);
5235 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
5243 bool VisitCastExpr(
const CastExpr *E) {
5246 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5248 case CK_DerivedToBase:
5249 case CK_UncheckedDerivedToBase:
5294 class LValueExprEvaluator
5295 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
5297 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
5298 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
5300 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
5304 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
5308 bool VisitStringLiteral(
const StringLiteral *E) {
return Success(E); }
5309 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
5317 return VisitUnaryPreIncDec(UO);
5320 return VisitUnaryPreIncDec(UO);
5325 bool VisitCastExpr(
const CastExpr *E) {
5328 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
5330 case CK_LValueBitCast:
5331 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5334 Result.Designator.setInvalid();
5337 case CK_BaseToDerived:
5352 bool InvalidBaseOK) {
5355 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
5358 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
5362 return VisitVarDecl(E, VD);
5364 return Visit(BD->getBinding());
5369 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
5376 isa<DeclRefExpr>(E) &&
5377 cast<DeclRefExpr>(E)->refersToEnclosingVariableOrCapture()) {
5382 if (Info.checkingPotentialConstantExpression())
5385 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
5387 Result = *Info.CurrentCall->This;
5394 if (FD->getType()->isReferenceType()) {
5399 Result.setFrom(Info.Ctx, RVal);
5404 CallStackFrame *Frame =
nullptr;
5412 if (Info.CurrentCall->Callee &&
5414 Frame = Info.CurrentCall;
5420 Result.set({VD, Frame->Index,
5421 Info.CurrentCall->getCurrentTemporaryVersion(VD)});
5431 if (!Info.checkingPotentialConstantExpression())
5432 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
5435 return Success(*V, E);
5438 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
5444 skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
5447 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
5456 Value = Info.Ctx.getMaterializedTemporaryValue(E,
true);
5475 for (
unsigned I = Adjustments.size(); I != 0; ) {
5477 switch (Adjustments[I].
Kind) {
5482 Type = Adjustments[I].DerivedToBase.BasePath->getType();
5488 Type = Adjustments[I].Field->getType();
5493 Adjustments[I].Ptr.RHS))
5495 Type = Adjustments[I].Ptr.MPT->getPointeeType();
5505 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
5506 "lvalue compound literal in c++?");
5512 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
5516 Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
5522 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
5526 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
5529 VisitIgnoredBaseExpression(E->
getBase());
5530 return VisitVarDecl(E, VD);
5535 if (MD->isStatic()) {
5536 VisitIgnoredBaseExpression(E->
getBase());
5542 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
5550 bool Success =
true;
5552 if (!Info.noteFailure())
5565 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
5569 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
5578 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
5580 "lvalue __imag__ on scalar?");
5587 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
5588 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5599 bool LValueExprEvaluator::VisitCompoundAssignOperator(
5601 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5607 if (!this->Visit(CAO->
getLHS())) {
5608 if (Info.noteFailure())
5622 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
5623 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5628 if (!this->Visit(E->
getLHS())) {
5629 if (Info.noteFailure())
5653 llvm::APInt &Result) {
5654 const AllocSizeAttr *AllocSize = getAllocSizeAttr(Call);
5656 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
5657 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
5662 auto EvaluateAsSizeT = [&](
const Expr *E, APSInt &Into) {
5667 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
5669 Into = Into.zextOrSelf(BitsInSizeT);
5674 if (!EvaluateAsSizeT(Call->
getArg(SizeArgNo), SizeOfElem))
5677 if (!AllocSize->getNumElemsParam().isValid()) {
5678 Result = std::move(SizeOfElem);
5682 APSInt NumberOfElems;
5683 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
5684 if (!EvaluateAsSizeT(Call->
getArg(NumArgNo), NumberOfElems))
5688 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
5692 Result = std::move(BytesAvailable);
5700 llvm::APInt &Result) {
5701 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
5702 "Can't get the size of a non alloc_size function");
5703 const auto *Base = LVal.getLValueBase().get<
const Expr *>();
5704 const CallExpr *CE = tryUnwrapAllocSizeCall(Base);
5732 if (!tryUnwrapAllocSizeCall(E))
5737 Result.setInvalid(E);
5740 Result.addUnsizedArray(Info, E, Pointee);
5745 class PointerExprEvaluator
5746 :
public ExprEvaluatorBase<PointerExprEvaluator> {
5750 bool Success(
const Expr *E) {
5755 bool evaluateLValue(
const Expr *E, LValue &Result) {
5759 bool evaluatePointer(
const Expr *E, LValue &Result) {
5763 bool visitNonBuiltinCallExpr(
const CallExpr *E);
5766 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
5767 : ExprEvaluatorBaseTy(info),
Result(Result),
5768 InvalidBaseOK(InvalidBaseOK) {}
5771 Result.setFrom(Info.Ctx, V);
5774 bool ZeroInitialization(
const Expr *E) {
5775 auto TargetVal = Info.Ctx.getTargetNullPointerValue(E->
getType());
5776 Result.setNull(E->
getType(), TargetVal);
5781 bool VisitCastExpr(
const CastExpr* E);
5784 {
return Success(E); }
5786 if (Info.noteFailure())
5791 {
return Success(E); }
5792 bool VisitCallExpr(
const CallExpr *E);
5793 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
5794 bool VisitBlockExpr(
const BlockExpr *E) {
5801 if (Info.checkingPotentialConstantExpression())
5803 if (!Info.CurrentCall->This) {
5804 if (Info.getLangOpts().CPlusPlus11)
5805 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
5810 Result = *Info.CurrentCall->This;
5819 Info.CurrentCall->LambdaThisCaptureField))
5822 if (Info.CurrentCall->LambdaThisCaptureField->getType()
5823 ->isPointerType()) {
5829 Result.setFrom(Info.Ctx, RVal);
5840 bool InvalidBaseOK) {
5842 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
5845 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
5848 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
5853 std::swap(PExp, IExp);
5855 bool EvalPtrOK = evaluatePointer(PExp, Result);
5856 if (!EvalPtrOK && !Info.noteFailure())
5870 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
5874 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5882 case CK_CPointerToObjCPointerCast:
5883 case CK_BlockPointerToObjCPointerCast:
5884 case CK_AnyPointerToBlockPointerCast:
5885 case CK_AddressSpaceConversion:
5886 if (!Visit(SubExpr))
5892 Result.Designator.setInvalid();
5894 CCEDiag(E, diag::note_constexpr_invalid_cast)
5897 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5899 if (E->
getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
5900 ZeroInitialization(E);
5903 case CK_DerivedToBase:
5904 case CK_UncheckedDerivedToBase:
5907 if (!Result.Base && Result.Offset.isZero())
5913 castAs<PointerType>()->getPointeeType(),
5916 case CK_BaseToDerived:
5919 if (!Result.Base && Result.Offset.isZero())
5923 case CK_NullToPointer:
5925 return ZeroInitialization(E);
5927 case CK_IntegralToPointer: {
5928 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5934 if (Value.
isInt()) {
5935 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
5936 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
5937 Result.Base = (
Expr*)
nullptr;
5938 Result.InvalidBase =
false;
5940 Result.Designator.setInvalid();
5941 Result.IsNullPtr =
false;
5945 Result.setFrom(Info.Ctx, Value);
5950 case CK_ArrayToPointerDecay: {
5952 if (!evaluateLValue(SubExpr, Result))
5961 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
5962 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
5963 Result.addArray(Info, E, CAT);
5969 case CK_FunctionToPointerDecay:
5970 return evaluateLValue(SubExpr, Result);
5972 case CK_LValueToRValue: {
5981 return InvalidBaseOK &&
5983 return Success(RVal, E);
5987 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6001 const bool AlignOfReturnsPreferred =
6008 return Info.Ctx.toCharUnitsFromBits(
6009 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
6012 return Info.Ctx.getTypeAlignInChars(T.
getTypePtr());
6014 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
6027 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
6028 return Info.Ctx.getDeclAlign(DRE->getDecl(),
6031 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
6032 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
6039 bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
6040 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
6043 if (!(InvalidBaseOK && getAllocSizeAttr(E)))
6046 Result.setInvalid(E);
6048 Result.addUnsizedArray(Info, E, PointeeTy);
6052 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
6057 return VisitBuiltinCallExpr(E, BuiltinOp);
6059 return visitNonBuiltinCallExpr(E);
6062 bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
6063 unsigned BuiltinOp) {
6064 switch (BuiltinOp) {
6065 case Builtin::BI__builtin_addressof:
6067 case Builtin::BI__builtin_assume_aligned: {
6074 LValue OffsetResult(Result);
6085 int64_t AdditionalOffset = -Offset.getZExtValue();
6090 if (OffsetResult.Base) {
6093 OffsetResult.Base.dyn_cast<
const ValueDecl*>()) {
6094 BaseAlignment = Info.Ctx.getDeclAlign(VD);
6100 if (BaseAlignment < Align) {
6101 Result.Designator.setInvalid();
6104 diag::note_constexpr_baa_insufficient_alignment) << 0
6112 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
6113 Result.Designator.setInvalid();
6117 diag::note_constexpr_baa_insufficient_alignment) << 1
6119 diag::note_constexpr_baa_value_insufficient_alignment))
6120 << (int)OffsetResult.Offset.getQuantity()
6127 case Builtin::BI__builtin_launder:
6129 case Builtin::BIstrchr:
6130 case Builtin::BIwcschr:
6131 case Builtin::BImemchr:
6132 case Builtin::BIwmemchr:
6133 if (Info.getLangOpts().CPlusPlus11)
6134 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
6136 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
6138 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
6140 case Builtin::BI__builtin_strchr:
6141 case Builtin::BI__builtin_wcschr:
6142 case Builtin::BI__builtin_memchr:
6143 case Builtin::BI__builtin_char_memchr:
6144 case Builtin::BI__builtin_wmemchr: {
6145 if (!Visit(E->
getArg(0)))
6150 uint64_t MaxLength = uint64_t(-1);
6151 if (BuiltinOp != Builtin::BIstrchr &&
6152 BuiltinOp != Builtin::BIwcschr &&
6153 BuiltinOp != Builtin::BI__builtin_strchr &&
6154 BuiltinOp != Builtin::BI__builtin_wcschr) {
6158 MaxLength = N.getExtValue();
6161 if (MaxLength == 0u)
6162 return ZeroInitialization(E);
6163 if (!Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
6164 Result.Designator.Invalid)
6166 QualType CharTy = Result.Designator.getType(Info.Ctx);
6167 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
6168 BuiltinOp == Builtin::BI__builtin_memchr;
6170 Info.Ctx.hasSameUnqualifiedType(
6174 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
6179 if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) !=
CharUnits::One())
6183 uint64_t DesiredVal;
6184 bool StopAtNull =
false;
6185 switch (BuiltinOp) {
6186 case Builtin::BIstrchr:
6187 case Builtin::BI__builtin_strchr:
6194 return ZeroInitialization(E);
6197 case Builtin::BImemchr:
6198 case Builtin::BI__builtin_memchr:
6199 case Builtin::BI__builtin_char_memchr:
6203 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
6206 case Builtin::BIwcschr:
6207 case Builtin::BI__builtin_wcschr:
6210 case Builtin::BIwmemchr:
6211 case Builtin::BI__builtin_wmemchr:
6213 DesiredVal = Desired.getZExtValue();
6217 for (; MaxLength; --MaxLength) {
6222 if (Char.
getInt().getZExtValue() == DesiredVal)
6224 if (StopAtNull && !Char.
getInt())
6230 return ZeroInitialization(E);
6233 case Builtin::BImemcpy:
6234 case Builtin::BImemmove:
6235 case Builtin::BIwmemcpy:
6236 case Builtin::BIwmemmove:
6237 if (Info.getLangOpts().CPlusPlus11)
6238 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
6240 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
6242 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
6244 case Builtin::BI__builtin_memcpy:
6245 case Builtin::BI__builtin_memmove:
6246 case Builtin::BI__builtin_wmemcpy:
6247 case Builtin::BI__builtin_wmemmove: {
6248 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
6249 BuiltinOp == Builtin::BIwmemmove ||
6250 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
6251 BuiltinOp == Builtin::BI__builtin_wmemmove;
6252 bool Move = BuiltinOp == Builtin::BImemmove ||
6253 BuiltinOp == Builtin::BIwmemmove ||
6254 BuiltinOp == Builtin::BI__builtin_memmove ||
6255 BuiltinOp == Builtin::BI__builtin_wmemmove;
6258 if (!Visit(E->
getArg(0)))
6269 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
6279 if (!Src.Base || !Dest.Base) {
6281 (!Src.Base ? Src : Dest).moveInto(Val);
6282 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
6283 << Move << WChar << !!Src.Base
6287 if (Src.Designator.Invalid || Dest.Designator.Invalid)
6293 QualType T = Dest.Designator.getType(Info.Ctx);
6294 QualType SrcT = Src.Designator.getType(Info.Ctx);
6295 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
6296 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << SrcT << T;
6300 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) << Move << T;
6304 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) << Move << T;
6309 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
6312 llvm::APInt OrigN = N;
6313 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
6315 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
6316 << Move << WChar << 0 << T << OrigN.toString(10,
false)
6325 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
6326 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
6327 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
6328 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
6329 << Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
6330 << N.toString(10,
false);
6333 uint64_t NElems = N.getZExtValue();
6334 uint64_t NBytes = NElems * TSize;
6339 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
6340 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
6341 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
6344 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
6352 }
else if (!Move && SrcOffset >= DestOffset &&
6353 SrcOffset - DestOffset < NBytes) {
6355 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
6376 return visitNonBuiltinCallExpr(E);
6385 class MemberPointerExprEvaluator
6386 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
6390 Result = MemberPtr(D);
6395 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
6396 : ExprEvaluatorBaseTy(Info),
Result(Result) {}
6402 bool ZeroInitialization(
const Expr *E) {
6403 return Success((
const ValueDecl*)
nullptr);
6406 bool VisitCastExpr(
const CastExpr *E);
6414 return MemberPointerExprEvaluator(Info, Result).Visit(E);
6417 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6420 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6422 case CK_NullToMemberPointer:
6424 return ZeroInitialization(E);
6426 case CK_BaseToDerivedMemberPointer: {
6434 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
6436 PathI != PathE; ++PathI) {
6437 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
6438 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
6439 if (!Result.castToDerived(Derived))
6448 case CK_DerivedToBaseMemberPointer:
6452 PathE = E->
path_end(); PathI != PathE; ++PathI) {
6453 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
6454 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
6455 if (!Result.castToBase(Base))
6462 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
6465 return Success(cast<DeclRefExpr>(E->
getSubExpr())->getDecl());
6473 class RecordExprEvaluator
6474 :
public ExprEvaluatorBase<RecordExprEvaluator> {
6479 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
6480 : ExprEvaluatorBaseTy(info), This(This),
Result(Result) {}
6486 bool ZeroInitialization(
const Expr *E) {
6487 return ZeroInitialization(E, E->
getType());
6491 bool VisitCallExpr(
const CallExpr *E) {
6492 return handleCallExpr(E, Result, &This);
6494 bool VisitCastExpr(
const CastExpr *E);
6497 return VisitCXXConstructExpr(E, E->
getType());
6517 const LValue &This,
APValue &Result) {
6518 assert(!RD->
isUnion() &&
"Expected non-union class type");
6529 End = CD->bases_end(); I !=
End; ++I, ++Index) {
6530 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
6531 LValue Subobject = This;
6535 Result.getStructBase(Index)))
6540 for (
const auto *I : RD->
fields()) {
6542 if (I->getType()->isReferenceType())
6545 LValue Subobject = This;
6551 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
6558 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
6570 LValue Subobject = This;
6575 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
6578 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
6579 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
6586 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6589 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6591 case CK_ConstructorConversion:
6594 case CK_DerivedToBase:
6595 case CK_UncheckedDerivedToBase: {
6603 APValue *Value = &DerivedObject;
6606 PathE = E->
path_end(); PathI != PathE; ++PathI) {
6607 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
6608 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
6618 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6640 LValue Subobject = This;
6645 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
6646 isa<CXXDefaultInitExpr>(InitExpr));
6648 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
6652 if (Result.isUninit())
6655 unsigned ElementNo = 0;
6656 bool Success =
true;
6660 for (
const auto &Base : CXXRD->bases()) {
6661 assert(ElementNo < E->getNumInits() &&
"missing init for base class");
6664 LValue Subobject = This;
6668 APValue &FieldVal = Result.getStructBase(ElementNo);
6670 if (!Info.noteFailure())
6679 for (
const auto *Field : RD->
fields()) {
6682 if (Field->isUnnamedBitfield())
6685 LValue Subobject = This;
6692 Subobject, Field, &Layout))
6698 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
6701 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
6702 isa<CXXDefaultInitExpr>(Init));
6704 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
6707 FieldVal, Field))) {
6708 if (!Info.noteFailure())
6727 if (!Result.isUninit())
6738 return ZeroInitialization(E, T);
6742 auto Body = FD->
getBody(Definition);
6750 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
6751 return Visit(ME->GetTemporaryExpr());
6753 if (ZeroInit && !ZeroInitialization(E, T))
6758 cast<CXXConstructorDecl>(Definition), Info,
6762 bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
6764 if (!Info.CurrentCall) {
6765 assert(Info.checkingPotentialConstantExpression());
6774 auto Body = FD->
getBody(Definition);
6780 cast<CXXConstructorDecl>(Definition), Info,
6784 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
6794 Array.addArray(Info, E, ArrayType);
6803 if (!Field->getType()->isPointerType() ||
6804 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
6810 Array.moveInto(Result.getStructField(0));
6815 if (Field->getType()->isPointerType() &&
6816 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
6821 ArrayType->
getSize().getZExtValue()))
6823 Array.moveInto(Result.getStructField(1));
6824 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
6826 Result.getStructField(1) =
APValue(APSInt(ArrayType->
getSize()));
6836 bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
6840 if (Info.checkingPotentialConstantExpression())
return true;
6842 const size_t NumFields =
6847 "The number of lambda capture initializers should equal the number of " 6848 "fields within the closure type");
6855 bool Success =
true;
6856 for (
const auto *Field : ClosureClass->
fields()) {
6859 Expr *
const CurFieldInit = *CaptureInitIt++;
6866 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
6868 if (!Info.keepEvaluatingAfterFailure())
6878 APValue &Result, EvalInfo &Info) {
6880 "can't evaluate expression as a record rvalue");
6881 return RecordExprEvaluator(Info, This, Result).Visit(E);
6892 class TemporaryExprEvaluator
6893 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
6895 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
6896 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
6899 bool VisitConstructExpr(
const Expr *E) {
6904 bool VisitCastExpr(
const CastExpr *E) {
6907 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
6909 case CK_ConstructorConversion:
6914 return VisitConstructExpr(E);
6917 return VisitConstructExpr(E);
6919 bool VisitCallExpr(
const CallExpr *E) {
6920 return VisitConstructExpr(E);
6923 return VisitConstructExpr(E);
6926 return VisitConstructExpr(E);
6934 return TemporaryExprEvaluator(Info, Result).Visit(E);
6942 class VectorExprEvaluator
6943 :
public ExprEvaluatorBase<VectorExprEvaluator> {
6947 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
6948 : ExprEvaluatorBaseTy(info),
Result(Result) {}
6953 Result =
APValue(V.data(), V.size());
6961 bool ZeroInitialization(
const Expr *E);
6965 bool VisitCastExpr(
const CastExpr* E);
6976 return VectorExprEvaluator(Info, Result).Visit(E);
6979 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6987 case CK_VectorSplat: {
6993 Val =
APValue(std::move(IntResult));
6995 APFloat FloatResult(0.0);
6998 Val =
APValue(std::move(FloatResult));
7005 return Success(Elts, E);
7009 llvm::APInt SValInt;
7014 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
7015 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7018 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
7019 unsigned FloatEltSize = EltSize;
7020 if (&Sem == &APFloat::x87DoubleExtended())
7022 for (
unsigned i = 0; i < NElts; i++) {
7025 Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
7027 Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
7028 Elts.push_back(
APValue(APFloat(Sem, Elt)));
7031 for (
unsigned i = 0; i < NElts; i++) {
7034 Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
7036 Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
7042 return Success(Elts, E);
7045 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7050 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
7062 unsigned CountInits = 0, CountElts = 0;
7063 while (CountElts < NumElements) {
7065 if (CountInits < NumInits
7071 for (
unsigned j = 0; j < vlen; j++)
7075 llvm::APSInt sInt(32);
7076 if (CountInits < NumInits) {
7080 sInt = Info.Ctx.MakeIntValue(0, EltTy);
7081 Elements.push_back(
APValue(sInt));
7084 llvm::APFloat f(0.0);
7085 if (CountInits < NumInits) {
7089 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
7090 Elements.push_back(
APValue(f));
7095 return Success(Elements, E);
7099 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
7103 if (EltTy->isIntegerType())
7104 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
7107 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
7110 return Success(Elements, E);
7113 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
7115 return ZeroInitialization(E);
7123 class ArrayExprEvaluator
7124 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
7129 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
7130 : ExprEvaluatorBaseTy(Info), This(This),
Result(Result) {}
7134 "expected array or string literal");
7139 bool ZeroInitialization(
const Expr *E) {
7141 Info.Ctx.getAsConstantArrayType(E->
getType());
7146 CAT->
getSize().getZExtValue());
7150 LValue Subobject = This;
7151 Subobject.addArray(Info, E, CAT);
7156 bool VisitCallExpr(
const CallExpr *E) {
7157 return handleCallExpr(E, Result, &This);
7163 const LValue &Subobject,
7169 APValue &Result, EvalInfo &Info) {
7171 return ArrayExprEvaluator(Info, This, Result).Visit(E);
7178 if (isa<ImplicitValueInitExpr>(FillerExpr))
7180 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
7181 for (
unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) {
7190 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
7203 return Success(Val, E);
7206 bool Success =
true;
7208 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
7209 "zero-initialized array shouldn't have any initialized elts");
7211 if (Result.isArray() && Result.hasArrayFiller())
7212 Filler = Result.getArrayFiller();
7215 unsigned NumElts = CAT->
getSize().getZExtValue();
7221 NumEltsToInit = NumElts;
7223 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: " 7224 << NumEltsToInit <<
".\n");
7231 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I)
7232 Result.getArrayInitializedElt(I) = Filler;
7233 if (Result.hasArrayFiller())
7234 Result.getArrayFiller() = Filler;
7237 LValue Subobject = This;
7238 Subobject.addArray(Info, E, CAT);
7239 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
7243 Info, Subobject, Init) ||
7246 if (!Info.noteFailure())
7252 if (!Result.hasArrayFiller())
7257 assert(FillerExpr &&
"no array filler for incomplete init list");
7259 FillerExpr) && Success;
7270 uint64_t Elements = CAT->getSize().getZExtValue();
7273 LValue Subobject = This;
7274 Subobject.addArray(Info, E, CAT);
7276 bool Success =
true;
7277 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
7281 CAT->getElementType(), 1)) {
7282 if (!Info.noteFailure())
7291 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
7292 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
7296 const LValue &Subobject,
7299 bool HadZeroInit = !Value->
isUninit();
7302 unsigned N = CAT->getSize().getZExtValue();
7312 for (
unsigned I = 0; I != N; ++I)
7316 LValue ArrayElt = Subobject;
7317 ArrayElt.addArray(Info, E, CAT);
7318 for (
unsigned I = 0; I != N; ++I)
7320 CAT->getElementType()) ||
7322 CAT->getElementType(), 1))
7331 return RecordExprEvaluator(Info, Subobject, *Value)
7332 .VisitCXXConstructExpr(E, Type);
7344 class IntExprEvaluator
7345 :
public ExprEvaluatorBase<IntExprEvaluator> {
7348 IntExprEvaluator(EvalInfo &info,
APValue &result)
7349 : ExprEvaluatorBaseTy(info),
Result(result) {}
7351 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
7353 "Invalid evaluation result.");
7355 "Invalid evaluation result.");
7356 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7357 "Invalid evaluation result.");
7361 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
7362 return Success(SI, E, Result);
7365 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
7367 "Invalid evaluation result.");
7368 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7369 "Invalid evaluation result.");
7371 Result.
getInt().setIsUnsigned(
7375 bool Success(
const llvm::APInt &I,
const Expr *E) {
7376 return Success(I, E, Result);
7379 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
7381 "Invalid evaluation result.");
7385 bool Success(uint64_t Value,
const Expr *E) {
7386 return Success(Value, E, Result);
7398 return Success(V.
getInt(), E);
7401 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
7416 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
7418 if (CheckReferencedDecl(E, E->
getDecl()))
7421 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
7425 VisitIgnoredBaseExpression(E->
getBase());
7429 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
7432 bool VisitCallExpr(
const CallExpr *E);
7433 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
7438 bool VisitCastExpr(
const CastExpr* E);
7450 if (Info.ArrayInitIndex == uint64_t(-1)) {
7456 return Success(Info.ArrayInitIndex, E);
7461 return ZeroInitialization(E);
7485 class FixedPointExprEvaluator
7486 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
7490 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
7491 : ExprEvaluatorBaseTy(info),
Result(result) {}
7493 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
7496 "Invalid evaluation result.");
7497 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7498 "Invalid evaluation result.");
7502 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
7503 return Success(SI, E, Result);
7506 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
7508 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7509 "Invalid evaluation result.");
7514 bool Success(
const llvm::APInt &I,
const Expr *E) {
7515 return Success(I, E, Result);
7518 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
7523 bool Success(uint64_t Value,
const Expr *E) {
7524 return Success(Value, E, Result);
7536 return Success(V.
getInt(), E);
7539 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
7564 return IntExprEvaluator(Info, Result).Visit(E);
7574 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
7584 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
7588 bool SameSign = (ECD->getInitVal().isSigned()
7590 bool SameWidth = (ECD->getInitVal().getBitWidth()
7591 == Info.Ctx.getIntWidth(E->
getType()));
7592 if (SameSign && SameWidth)
7593 return Success(ECD->getInitVal(), E);
7597 llvm::APSInt Val = ECD->getInitVal();
7599 Val.setIsSigned(!ECD->getInitVal().isSigned());
7601 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
7602 return Success(Val, E);
7647 switch (CanTy->getTypeClass()) {
7648 #define TYPE(ID, BASE) 7649 #define DEPENDENT_TYPE(ID, BASE) case Type::ID: 7650 #define NON_CANONICAL_TYPE(ID, BASE) case Type::ID: 7651 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID: 7652 #include "clang/AST/TypeNodes.def" 7654 case Type::DeducedTemplateSpecialization:
7655 llvm_unreachable(
"unexpected non-canonical or dependent type");
7659 #define BUILTIN_TYPE(ID, SINGLETON_ID) 7660 #define SIGNED_TYPE(ID, SINGLETON_ID) \ 7661 case BuiltinType::ID: return GCCTypeClass::Integer; 7662 #define FLOATING_TYPE(ID, SINGLETON_ID) \ 7663 case BuiltinType::ID: return GCCTypeClass::RealFloat; 7664 #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \ 7665 case BuiltinType::ID: break; 7666 #include "clang/AST/BuiltinTypes.def" 7667 case BuiltinType::Void:
7670 case BuiltinType::Bool:
7673 case BuiltinType::Char_U:
7674 case BuiltinType::UChar:
7675 case BuiltinType::WChar_U:
7676 case BuiltinType::Char8:
7677 case BuiltinType::Char16:
7678 case BuiltinType::Char32:
7679 case BuiltinType::UShort:
7680 case BuiltinType::UInt:
7681 case BuiltinType::ULong:
7682 case BuiltinType::ULongLong:
7683 case BuiltinType::UInt128:
7686 case BuiltinType::UShortAccum:
7687 case BuiltinType::UAccum:
7688 case BuiltinType::ULongAccum:
7689 case BuiltinType::UShortFract:
7690 case BuiltinType::UFract:
7691 case BuiltinType::ULongFract:
7692 case BuiltinType::SatUShortAccum:
7693 case BuiltinType::SatUAccum:
7694 case BuiltinType::SatULongAccum:
7695 case BuiltinType::SatUShortFract:
7696 case BuiltinType::SatUFract:
7697 case BuiltinType::SatULongFract:
7700 case BuiltinType::NullPtr:
7702 case BuiltinType::ObjCId:
7703 case BuiltinType::ObjCClass:
7704 case BuiltinType::ObjCSel:
7705 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 7706 case BuiltinType::Id: 7707 #include "clang/Basic/OpenCLImageTypes.def" 7708 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 7709 case BuiltinType::Id: 7710 #include "clang/Basic/OpenCLExtensionTypes.def" 7711 case BuiltinType::OCLSampler:
7712 case BuiltinType::OCLEvent:
7713 case BuiltinType::OCLClkEvent:
7714 case BuiltinType::OCLQueue:
7715 case BuiltinType::OCLReserveID:
7718 case BuiltinType::Dependent:
7719 llvm_unreachable(
"unexpected dependent type");
7721 llvm_unreachable(
"unexpected placeholder type");
7727 case Type::ConstantArray:
7728 case Type::VariableArray:
7729 case Type::IncompleteArray:
7730 case Type::FunctionNoProto:
7731 case Type::FunctionProto:
7734 case Type::MemberPointer:
7735 return CanTy->isMemberDataPointerType()
7751 case Type::BlockPointer:
7753 case Type::ExtVector:
7754 case Type::ObjCObject:
7755 case Type::ObjCInterface:
7756 case Type::ObjCObjectPointer:
7762 case Type::LValueReference:
7763 case Type::RValueReference:
7764 llvm_unreachable(
"invalid type for expression");
7767 llvm_unreachable(
"unexpected type class");
7790 template<
typename LValue>
7792 const Expr *E = LV.getLValueBase().template dyn_cast<
const Expr*>();
7793 return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
7829 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
7844 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
7846 }
else if (
const Expr *E = B.
get<
const Expr*>()) {
7847 if (isa<CompoundLiteralExpr>(E))
7864 auto *Cast = dyn_cast<
CastExpr>(NoParens);
7865 if (Cast ==
nullptr)
7872 CastKind != CK_AddressSpaceConversion)
7875 auto *SubExpr = Cast->getSubExpr();
7876 if (!SubExpr->getType()->hasPointerRepresentation() || !SubExpr->isRValue())
7897 assert(!LVal.Designator.Invalid);
7899 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &Invalid) {
7902 if (Invalid || Parent->
isUnion())
7908 auto &Base = LVal.getLValueBase();
7909 if (
auto *ME = dyn_cast_or_null<MemberExpr>(Base.
dyn_cast<
const Expr *>())) {
7910 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
7912 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
7914 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
7915 for (
auto *FD : IFD->chain()) {
7917 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid))
7925 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
7935 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
7936 const auto &Entry = LVal.Designator.Entries[I];
7942 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
7943 uint64_t Index = Entry.ArrayIndex;
7944 if (Index + 1 != CAT->getSize())
7946 BaseType = CAT->getElementType();
7949 uint64_t Index = Entry.ArrayIndex;
7953 }
else if (
auto *FD = getAsField(Entry)) {
7955 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
7959 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
7971 if (LVal.Designator.Invalid)
7974 if (!LVal.Designator.Entries.empty())
7975 return LVal.Designator.isMostDerivedAnUnsizedArray();
7977 if (!LVal.InvalidBase)
7982 const auto *E = LVal.Base.dyn_cast<
const Expr *>();
7983 return !E || !isa<MemberExpr>(E);
7989 const SubobjectDesignator &
Designator = LVal.Designator;
8001 return LVal.InvalidBase &&
8002 Designator.Entries.size() == Designator.MostDerivedPathLength &&
8003 Designator.MostDerivedIsArrayElement &&
8012 if (Int.ugt(CharUnitsMax))
8025 unsigned Type,
const LValue &LVal,
8038 if (!(Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
8040 if (Type == 3 && !DetermineForCompleteObject)
8043 llvm::APInt APEndOffset;
8044 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
8048 if (LVal.InvalidBase)
8052 return CheckedHandleSizeof(BaseTy, EndOffset);
8056 const SubobjectDesignator &
Designator = LVal.Designator;
8068 llvm::APInt APEndOffset;
8069 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
8081 if (!CheckedHandleSizeof(Designator.MostDerivedType, BytesPerElem))
8087 int64_t ElemsRemaining;
8088 if (Designator.MostDerivedIsArrayElement &&
8089 Designator.Entries.size() == Designator.MostDerivedPathLength) {
8090 uint64_t ArraySize = Designator.getMostDerivedArraySize();
8091 uint64_t ArrayIndex = Designator.Entries.back().ArrayIndex;
8092 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
8094 ElemsRemaining = Designator.isOnePastTheEnd() ? 0 : 1;
8097 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
8107 EvalInfo &Info, uint64_t &Size) {
8114 SpeculativeEvaluationRAII SpeculativeEval(Info);
8115 IgnoreSideEffectsRAII Fold(Info);
8123 LVal.setFrom(Info.Ctx, RVal);
8131 if (LVal.getLValueOffset().isNegative()) {
8142 if (EndOffset <= LVal.getLValueOffset())
8145 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
8149 bool IntExprEvaluator::VisitConstantExpr(
const ConstantExpr *E) {
8151 return ExprEvaluatorBaseTy::VisitConstantExpr(E);
8154 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
8156 return VisitBuiltinCallExpr(E, BuiltinOp);
8158 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8161 bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
8162 unsigned BuiltinOp) {
8165 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8167 case Builtin::BI__builtin_object_size: {
8171 assert(Type <= 3 &&
"unexpected type");
8175 return Success(Size, E);
8178 return Success((Type & 2) ? 0 : -1, E);
8182 switch (Info.EvalMode) {
8183 case EvalInfo::EM_ConstantExpression:
8184 case EvalInfo::EM_PotentialConstantExpression:
8185 case EvalInfo::EM_ConstantFold:
8186 case EvalInfo::EM_EvaluateForOverflow:
8187 case EvalInfo::EM_IgnoreSideEffects:
8190 case EvalInfo::EM_ConstantExpressionUnevaluated:
8191 case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
8193 return Success((Type & 2) ? 0 : -1, E);
8196 llvm_unreachable(
"unexpected EvalMode");
8199 case Builtin::BI__builtin_os_log_format_buffer_size: {
8205 case Builtin::BI__builtin_bswap16:
8206 case Builtin::BI__builtin_bswap32:
8207 case Builtin::BI__builtin_bswap64: {
8212 return Success(Val.byteSwap(), E);
8215 case Builtin::BI__builtin_classify_type:
8218 case Builtin::BI__builtin_clrsb:
8219 case Builtin::BI__builtin_clrsbl:
8220 case Builtin::BI__builtin_clrsbll: {
8225 return Success(Val.getBitWidth() - Val.getMinSignedBits(), E);
8228 case Builtin::BI__builtin_clz:
8229 case Builtin::BI__builtin_clzl:
8230 case Builtin::BI__builtin_clzll:
8231 case Builtin::BI__builtin_clzs: {
8238 return Success(Val.countLeadingZeros(), E);
8241 case Builtin::BI__builtin_constant_p: {
8244 return Success(
true, E);
8245 auto ArgTy = Arg->IgnoreImplicit()->getType();
8246 if (!Info.InConstantContext && !Arg->HasSideEffects(Info.Ctx) &&
8247 !ArgTy->isAggregateType() && !ArgTy->isPointerType()) {
8250 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
8253 return Success(
false, E);
8256 case Builtin::BI__builtin_ctz:
8257 case Builtin::BI__builtin_ctzl:
8258 case Builtin::BI__builtin_ctzll:
8259 case Builtin::BI__builtin_ctzs: {
8266 return Success(Val.countTrailingZeros(), E);
8269 case Builtin::BI__builtin_eh_return_data_regno: {
8271 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
8272 return Success(Operand, E);
8275 case Builtin::BI__builtin_expect:
8276 return Visit(E->
getArg(0));
8278 case Builtin::BI__builtin_ffs:
8279 case Builtin::BI__builtin_ffsl:
8280 case Builtin::BI__builtin_ffsll: {
8285 unsigned N = Val.countTrailingZeros();
8286 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
8289 case Builtin::BI__builtin_fpclassify: {
8294 switch (Val.getCategory()) {
8295 case APFloat::fcNaN: Arg = 0;
break;
8296 case APFloat::fcInfinity: Arg = 1;
break;
8297 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
8298 case APFloat::fcZero: Arg = 4;
break;
8300 return Visit(E->
getArg(Arg));
8303 case Builtin::BI__builtin_isinf_sign: {
8306 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
8309 case Builtin::BI__builtin_isinf: {
8312 Success(Val.isInfinity() ? 1 : 0, E);
8315 case Builtin::BI__builtin_isfinite: {
8318 Success(Val.isFinite() ? 1 : 0, E);
8321 case Builtin::BI__builtin_isnan: {
8324 Success(Val.isNaN() ? 1 : 0, E);
8327 case Builtin::BI__builtin_isnormal: {
8330 Success(Val.isNormal() ? 1 : 0, E);
8333 case Builtin::BI__builtin_parity:
8334 case Builtin::BI__builtin_parityl:
8335 case Builtin::BI__builtin_parityll: {
8340 return Success(Val.countPopulation() % 2, E);
8343 case Builtin::BI__builtin_popcount:
8344 case Builtin::BI__builtin_popcountl:
8345 case Builtin::BI__builtin_popcountll: {
8350 return Success(Val.countPopulation(), E);
8353 case Builtin::BIstrlen:
8354 case Builtin::BIwcslen:
8356 if (Info.getLangOpts().CPlusPlus11)
8357 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
8359 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
8361 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
8363 case Builtin::BI__builtin_strlen:
8364 case Builtin::BI__builtin_wcslen: {
8374 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
8375 String.getLValueBase().dyn_cast<
const Expr *>())) {
8378 StringRef Str = S->getBytes();
8379 int64_t Off = String.Offset.getQuantity();
8380 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
8381 S->getCharByteWidth() == 1 &&
8383 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
8384 Str = Str.substr(Off);
8386 StringRef::size_type Pos = Str.find(0);
8387 if (Pos != StringRef::npos)
8388 Str = Str.substr(0, Pos);
8390 return Success(Str.size(), E);
8397 for (uint64_t Strlen = 0; ; ++Strlen) {
8403 return Success(Strlen, E);
8409 case Builtin::BIstrcmp:
8410 case Builtin::BIwcscmp:
8411 case Builtin::BIstrncmp:
8412 case Builtin::BIwcsncmp:
8413 case Builtin::BImemcmp:
8414 case Builtin::BIwmemcmp:
8416 if (Info.getLangOpts().CPlusPlus11)
8417 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
8419 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
8421 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
8423 case Builtin::BI__builtin_strcmp:
8424 case Builtin::BI__builtin_wcscmp:
8425 case Builtin::BI__builtin_strncmp:
8426 case Builtin::BI__builtin_wcsncmp:
8427 case Builtin::BI__builtin_memcmp:
8428 case Builtin::BI__builtin_wmemcmp: {
8429 LValue String1, String2;
8434 uint64_t MaxLength = uint64_t(-1);
8435 if (BuiltinOp != Builtin::BIstrcmp &&
8436 BuiltinOp != Builtin::BIwcscmp &&
8437 BuiltinOp != Builtin::BI__builtin_strcmp &&
8438 BuiltinOp != Builtin::BI__builtin_wcscmp) {
8442 MaxLength = N.getExtValue();
8446 if (MaxLength == 0u)
8447 return Success(0, E);
8449 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
8450 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
8451 String1.Designator.Invalid || String2.Designator.Invalid)
8454 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
8455 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
8457 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
8458 BuiltinOp == Builtin::BI__builtin_memcmp;
8461 (Info.Ctx.hasSameUnqualifiedType(
8463 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
8468 Char1.
isInt() && Char2.isInt();
8470 const auto &AdvanceElems = [&] {
8476 uint64_t BytesRemaining = MaxLength;
8479 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy1;
8483 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy2;
8486 uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)};
8487 CharUnits CharTy1Size = Info.Ctx.toCharUnitsFromBits(CharTy1Width);
8489 if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2))
8491 uint64_t BytesPerElement = CharTy1Size.
getQuantity();
8492 assert(BytesRemaining &&
"BytesRemaining should not be zero: the " 8493 "following loop considers at least one element");
8496 if (!ReadCurElems(Char1, Char2))
8503 APSInt Char1InMem = Char1.
getInt().extOrTrunc(CharTy1Width);
8504 APSInt Char2InMem = Char2.
getInt().extOrTrunc(CharTy1Width);
8505 if (Char1InMem.ne(Char2InMem)) {
8508 if (BytesPerElement == 1u) {
8510 return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E);
8516 if (!AdvanceElems())
8518 if (BytesRemaining <= BytesPerElement)
8520 BytesRemaining -= BytesPerElement;
8523 return Success(0, E);
8526 bool StopAtNull = (BuiltinOp != Builtin::BImemcmp &&
8527 BuiltinOp != Builtin::BIwmemcmp &&
8528 BuiltinOp != Builtin::BI__builtin_memcmp &&
8529 BuiltinOp != Builtin::BI__builtin_wmemcmp);
8530 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
8531 BuiltinOp == Builtin::BIwcsncmp ||
8532 BuiltinOp == Builtin::BIwmemcmp ||
8533 BuiltinOp == Builtin::BI__builtin_wcscmp ||
8534 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
8535 BuiltinOp == Builtin::BI__builtin_wmemcmp;
8537 for (; MaxLength; --MaxLength) {
8539 if (!ReadCurElems(Char1, Char2))
8543 return Success(Char1.
getInt() < Char2.
getInt() ? -1 : 1, E);
8545 return Success(Char1.
getInt().ult(Char2.
getInt()) ? -1 : 1, E);
8547 if (StopAtNull && !Char1.
getInt())
8548 return Success(0, E);
8549 assert(!(StopAtNull && !Char2.
getInt()));
8550 if (!AdvanceElems())
8554 return Success(0, E);
8557 case Builtin::BI__atomic_always_lock_free:
8558 case Builtin::BI__atomic_is_lock_free:
8559 case Builtin::BI__c11_atomic_is_lock_free: {
8577 unsigned InlineWidthBits =
8578 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
8579 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
8580 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
8586 return Success(1, E);
8589 castAs<PointerType>()->getPointeeType();
8591 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
8593 return Success(1, E);
8598 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
8599 Success(0, E) :
Error(E);
8601 case Builtin::BIomp_is_initial_device:
8603 return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E);
8604 case Builtin::BI__builtin_add_overflow:
8605 case Builtin::BI__builtin_sub_overflow:
8606 case Builtin::BI__builtin_mul_overflow:
8607 case Builtin::BI__builtin_sadd_overflow:
8608 case Builtin::BI__builtin_uadd_overflow:
8609 case Builtin::BI__builtin_uaddl_overflow:
8610 case Builtin::BI__builtin_uaddll_overflow:
8611 case Builtin::BI__builtin_usub_overflow:
8612 case Builtin::BI__builtin_usubl_overflow:
8613 case Builtin::BI__builtin_usubll_overflow:
8614 case Builtin::BI__builtin_umul_overflow:
8615 case Builtin::BI__builtin_umull_overflow:
8616 case Builtin::BI__builtin_umulll_overflow:
8617 case Builtin::BI__builtin_saddl_overflow:
8618 case Builtin::BI__builtin_saddll_overflow:
8619 case Builtin::BI__builtin_ssub_overflow:
8620 case Builtin::BI__builtin_ssubl_overflow:
8621 case Builtin::BI__builtin_ssubll_overflow:
8622 case Builtin::BI__builtin_smul_overflow:
8623 case Builtin::BI__builtin_smull_overflow:
8624 case Builtin::BI__builtin_smulll_overflow: {
8625 LValue ResultLValue;
8635 bool DidOverflow =
false;
8638 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
8639 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
8640 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
8641 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
8643 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
8645 uint64_t LHSSize = LHS.getBitWidth();
8646 uint64_t RHSSize = RHS.getBitWidth();
8647 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
8654 if (IsSigned && !AllSigned)
8657 LHS = APSInt(IsSigned ? LHS.sextOrSelf(MaxBits) : LHS.zextOrSelf(MaxBits),
8659 RHS = APSInt(IsSigned ? RHS.sextOrSelf(MaxBits) : RHS.zextOrSelf(MaxBits),
8661 Result = APSInt(MaxBits, !IsSigned);
8665 switch (BuiltinOp) {
8667 llvm_unreachable(
"Invalid value for BuiltinOp");
8668 case Builtin::BI__builtin_add_overflow:
8669 case Builtin::BI__builtin_sadd_overflow:
8670 case Builtin::BI__builtin_saddl_overflow:
8671 case Builtin::BI__builtin_saddll_overflow:
8672 case Builtin::BI__builtin_uadd_overflow:
8673 case Builtin::BI__builtin_uaddl_overflow:
8674 case Builtin::BI__builtin_uaddll_overflow:
8675 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
8676 : LHS.uadd_ov(RHS, DidOverflow);
8678 case Builtin::BI__builtin_sub_overflow:
8679 case Builtin::BI__builtin_ssub_overflow:
8680 case Builtin::BI__builtin_ssubl_overflow:
8681 case Builtin::BI__builtin_ssubll_overflow:
8682 case Builtin::BI__builtin_usub_overflow:
8683 case Builtin::BI__builtin_usubl_overflow:
8684 case Builtin::BI__builtin_usubll_overflow:
8685 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
8686 : LHS.usub_ov(RHS, DidOverflow);
8688 case Builtin::BI__builtin_mul_overflow:
8689 case Builtin::BI__builtin_smul_overflow:
8690 case Builtin::BI__builtin_smull_overflow:
8691 case Builtin::BI__builtin_smulll_overflow:
8692 case Builtin::BI__builtin_umul_overflow:
8693 case Builtin::BI__builtin_umull_overflow:
8694 case Builtin::BI__builtin_umulll_overflow:
8695 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
8696 : LHS.umul_ov(RHS, DidOverflow);
8702 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
8703 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
8704 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
8710 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
8713 if (!APSInt::isSameValue(Temp, Result))
8721 return Success(DidOverflow, E);
8732 if (!LV.getLValueBase())
8737 if (!LV.getLValueDesignator().Invalid &&
8738 !LV.getLValueDesignator().isOnePastTheEnd())
8743 QualType Ty = getType(LV.getLValueBase());
8750 return LV.getLValueOffset() == Size;
8760 class DataRecursiveIntBinOpEvaluator {
8765 EvalResult() : Failed(
false) { }
8767 void swap(EvalResult &RHS) {
8769 Failed = RHS.Failed;
8776 EvalResult LHSResult;
8777 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
8780 Job(Job &&) =
default;
8782 void startSpeculativeEval(EvalInfo &Info) {
8783 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
8787 SpeculativeEvaluationRAII SpecEvalRAII;
8792 IntExprEvaluator &IntEval;
8797 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
8798 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
8813 EvalResult PrevResult;
8814 while (!Queue.empty())
8815 process(PrevResult);
8817 if (PrevResult.Failed)
return false;
8819 FinalResult.
swap(PrevResult.Val);
8824 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
8825 return IntEval.Success(Value, E, Result);
8827 bool Success(
const APSInt &Value,
const Expr *E,
APValue &Result) {
8828 return IntEval.Success(Value, E, Result);
8831 return IntEval.Error(E);
8834 return IntEval.Error(E, D);
8838 return Info.CCEDiag(E, D);
8842 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
8843 bool &SuppressRHSDiags);
8845 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
8848 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
8849 Result.Failed = !
Evaluate(Result.Val, Info, E);
8854 void process(EvalResult &Result);
8856 void enqueue(
const Expr *E) {
8858 Queue.resize(Queue.size()+1);
8860 Queue.back().Kind = Job::AnyExprKind;
8866 bool DataRecursiveIntBinOpEvaluator::
8867 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
8868 bool &SuppressRHSDiags) {
8871 if (LHSResult.Failed)
8872 return Info.noteSideEffect();
8881 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
8882 Success(LHSAsBool, E, LHSResult.Val);
8886 LHSResult.Failed =
true;
8890 if (!Info.noteSideEffect())
8896 SuppressRHSDiags =
true;
8905 if (LHSResult.Failed && !Info.noteFailure())
8916 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
8919 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
8921 : Offset64 + Index64);
8924 bool DataRecursiveIntBinOpEvaluator::
8925 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
8928 if (RHSResult.Failed)
8930 Result = RHSResult.Val;
8935 bool lhsResult, rhsResult;
8942 return Success(lhsResult || rhsResult, E, Result);
8944 return Success(lhsResult && rhsResult, E, Result);
8950 if (rhsResult == (E->
getOpcode() == BO_LOr))
8951 return Success(rhsResult, E, Result);
8961 if (LHSResult.Failed || RHSResult.Failed)
8964 const APValue &LHSVal = LHSResult.Val;
8965 const APValue &RHSVal = RHSResult.Val;
8989 if (!LHSExpr || !RHSExpr)
8993 if (!LHSAddrExpr || !RHSAddrExpr)
8997 RHSAddrExpr->getLabel()->getDeclContext())
8999 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
9015 return Success(Value, E, Result);
9018 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
9019 Job &job = Queue.back();
9022 case Job::AnyExprKind: {
9023 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
9024 if (shouldEnqueue(Bop)) {
9025 job.Kind = Job::BinOpKind;
9026 enqueue(Bop->getLHS());
9031 EvaluateExpr(job.E, Result);
9036 case Job::BinOpKind: {
9038 bool SuppressRHSDiags =
false;
9039 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
9043 if (SuppressRHSDiags)
9044 job.startSpeculativeEval(Info);
9045 job.LHSResult.swap(Result);
9046 job.Kind = Job::BinOpVisitedLHSKind;
9051 case Job::BinOpVisitedLHSKind: {
9055 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
9061 llvm_unreachable(
"Invalid Job::Kind!");
9067 class DelayedNoteFailureRAII {
9072 DelayedNoteFailureRAII(EvalInfo &Info,
bool NoteFailure =
true)
9073 : Info(Info), NoteFailure(NoteFailure) {}
9074 ~DelayedNoteFailureRAII() {
9076 bool ContinueAfterFailure = Info.noteFailure();
9077 (void)ContinueAfterFailure;
9078 assert(ContinueAfterFailure &&
9079 "Shouldn't have kept evaluating on failure.");
9085 template <
class SuccessCB,
class AfterCB>
9088 SuccessCB &&Success, AfterCB &&DoAfter) {
9092 "unsupported binary expression evaluation");
9094 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
9103 Info.Ctx.CompCategories.getInfoForType(E->
getType());
9115 if (!LHSOK && !Info.noteFailure())
9127 ComplexValue LHS, RHS;
9136 LHS.makeComplexFloat();
9137 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
9142 if (!LHSOK && !Info.noteFailure())
9148 RHS.makeComplexFloat();
9149 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
9153 if (LHS.isComplexFloat()) {
9154 APFloat::cmpResult CR_r =
9155 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
9156 APFloat::cmpResult CR_i =
9157 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
9158 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
9161 assert(IsEquality &&
"invalid complex comparison");
9162 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
9163 LHS.getComplexIntImag() == RHS.getComplexIntImag();
9170 APFloat RHS(0.0), LHS(0.0);
9173 if (!LHSOK && !Info.noteFailure())
9180 auto GetCmpRes = [&]() {
9181 switch (LHS.compare(RHS)) {
9182 case APFloat::cmpEqual:
9184 case APFloat::cmpLessThan:
9186 case APFloat::cmpGreaterThan:
9188 case APFloat::cmpUnordered:
9191 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
9193 return Success(GetCmpRes(), E);
9197 LValue LHSValue, RHSValue;
9200 if (!LHSOK && !Info.noteFailure())
9216 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
9217 (!RHSValue.Base && !RHSValue.Offset.isZero()))
9224 LHSValue.Base && RHSValue.Base)
9232 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
9234 (RHSValue.Base && RHSValue.Offset.isZero() &&
9245 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
9246 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
9248 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
9249 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
9259 Info.CCEDiag(E, diag::note_constexpr_void_comparison);
9269 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
9272 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
9279 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
9280 Mismatch < RHSDesignator.Entries.size()) {
9281 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
9282 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
9284 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
9286 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
9287 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
9290 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
9291 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
9296 diag::note_constexpr_pointer_comparison_differing_access)
9304 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
9307 assert(PtrSize <= 64 &&
"Unexpected pointer width");
9308 uint64_t Mask = ~0ULL >> (64 - PtrSize);
9315 if (!LHSValue.Base.isNull() && IsRelational) {
9316 QualType BaseTy = getType(LHSValue.Base);
9319 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
9321 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
9325 if (CompareLHS < CompareRHS)
9327 if (CompareLHS > CompareRHS)
9333 assert(IsEquality &&
"unexpected member pointer operation");
9336 MemberPtr LHSValue, RHSValue;
9339 if (!LHSOK && !Info.noteFailure())
9348 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
9349 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
9355 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
9356 if (MD->isVirtual())
9357 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
9358 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
9359 if (MD->isVirtual())
9360 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
9366 bool Equal = LHSValue == RHSValue;
9372 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
9391 Info.Ctx.CompCategories.getInfoForType(E->
getType());
9402 return ExprEvaluatorBaseTy::VisitBinCmp(E);
9406 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9412 DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->
isAssignmentOp());
9413 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
9414 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
9418 "DataRecursiveIntBinOpEvaluator should have handled integral types");
9432 llvm_unreachable(
"unsupported binary operator");
9435 return Success(IsEqual == (Op == BO_EQ), E);
9436 case BO_LT:
return Success(IsLess, E);
9437 case BO_GT:
return Success(IsGreater, E);
9438 case BO_LE:
return Success(IsEqual || IsLess, E);
9439 case BO_GE:
return Success(IsEqual || IsGreater, E);
9443 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9452 LValue LHSValue, RHSValue;
9455 if (!LHSOK && !Info.noteFailure())
9465 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
9467 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
9468 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
9469 if (!LHSExpr || !RHSExpr)
9473 if (!LHSAddrExpr || !RHSAddrExpr)
9477 RHSAddrExpr->getLabel()->getDeclContext())
9479 return Success(
APValue(LHSAddrExpr, RHSAddrExpr), E);
9481 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
9482 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
9484 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
9485 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
9491 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
9494 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
9506 if (ElementSize.
isZero()) {
9507 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
9520 APSInt LHS(llvm::APInt(65, (int64_t)LHSOffset.
getQuantity(),
true),
false);
9521 APSInt RHS(llvm::APInt(65, (int64_t)RHSOffset.
getQuantity(),
true),
false);
9522 APSInt ElemSize(llvm::APInt(65, (int64_t)ElementSize.
getQuantity(),
true),
9524 APSInt TrueResult = (LHS - RHS) / ElemSize;
9525 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
9527 if (Result.extend(65) != TrueResult &&
9530 return Success(Result, E);
9533 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9538 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
9562 return Success(n, E);
9564 return Success(1, E);
9577 return Success(Sizeof, E);
9582 Info.Ctx.toCharUnitsFromBits(
9588 llvm_unreachable(
"unknown expr/type trait");
9591 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
9597 for (
unsigned i = 0; i != n; ++i) {
9605 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
9609 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
9610 Result += IdxResult.getSExtValue() * ElementSize;
9623 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
9630 llvm_unreachable(
"dependent __builtin_offsetof");
9646 CurrentType = BaseSpec->
getType();
9657 return Success(Result, OOE);
9660 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
9676 if (!Result.isInt())
return Error(E);
9677 const APSInt &Value = Result.getInt();
9678 if (Value.isSigned() && Value.isMinSignedValue() && E->
canOverflow() &&
9682 return Success(-Value, E);
9687 if (!Result.isInt())
return Error(E);
9688 return Success(~Result.getInt(), E);
9694 return Success(!bres, E);
9701 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9707 case CK_BaseToDerived:
9708 case CK_DerivedToBase:
9709 case CK_UncheckedDerivedToBase:
9712 case CK_ArrayToPointerDecay:
9713 case CK_FunctionToPointerDecay:
9714 case CK_NullToPointer:
9715 case CK_NullToMemberPointer:
9716 case CK_BaseToDerivedMemberPointer:
9717 case CK_DerivedToBaseMemberPointer:
9718 case CK_ReinterpretMemberPointer:
9719 case CK_ConstructorConversion:
9720 case CK_IntegralToPointer:
9722 case CK_VectorSplat:
9723 case CK_IntegralToFloating:
9724 case CK_FloatingCast:
9725 case CK_CPointerToObjCPointerCast:
9726 case CK_BlockPointerToObjCPointerCast:
9727 case CK_AnyPointerToBlockPointerCast:
9728 case CK_ObjCObjectLValueCast:
9729 case CK_FloatingRealToComplex:
9730 case CK_FloatingComplexToReal:
9731 case CK_FloatingComplexCast:
9732 case CK_FloatingComplexToIntegralComplex:
9733 case CK_IntegralRealToComplex:
9734 case CK_IntegralComplexCast:
9735 case CK_IntegralComplexToFloatingComplex:
9736 case CK_BuiltinFnToFnPtr:
9737 case CK_ZeroToOCLOpaqueType:
9738 case CK_NonAtomicToAtomic:
9739 case CK_AddressSpaceConversion:
9740 case CK_IntToOCLSampler:
9741 case CK_FixedPointCast:
9742 llvm_unreachable(
"invalid cast kind for integral value");
9746 case CK_LValueBitCast:
9747 case CK_ARCProduceObject:
9748 case CK_ARCConsumeObject:
9749 case CK_ARCReclaimReturnedObject:
9750 case CK_ARCExtendBlockObject:
9751 case CK_CopyAndAutoreleaseBlockObject:
9754 case CK_UserDefinedConversion:
9755 case CK_LValueToRValue:
9756 case CK_AtomicToNonAtomic:
9758 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9760 case CK_MemberPointerToBoolean:
9761 case CK_PointerToBoolean:
9762 case CK_IntegralToBoolean:
9763 case CK_FloatingToBoolean:
9764 case CK_BooleanToSignedIntegral:
9765 case CK_FloatingComplexToBoolean:
9766 case CK_IntegralComplexToBoolean: {
9770 uint64_t IntResult = BoolResult;
9771 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
9772 IntResult = (uint64_t)-1;
9773 return Success(IntResult, E);
9776 case CK_FixedPointToBoolean: {
9781 return Success(Val.
getInt().getBoolValue(), E);
9784 case CK_IntegralCast: {
9785 if (!Visit(SubExpr))
9788 if (!Result.isInt()) {
9794 if (Result.isAddrLabelDiff())
9795 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
9797 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
9801 Result.getInt()), E);
9804 case CK_PointerToIntegral: {
9805 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
9811 if (LV.getLValueBase()) {
9816 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
9819 LV.Designator.setInvalid();
9820 LV.moveInto(Result);
9828 llvm_unreachable(
"Can't cast this!");
9833 case CK_IntegralComplexToReal: {
9837 return Success(C.getComplexIntReal(), E);
9840 case CK_FloatingToIntegral: {
9848 return Success(Value, E);
9852 llvm_unreachable(
"unknown cast resulting in integral value");
9855 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9860 if (!LV.isComplexInt())
9862 return Success(LV.getComplexIntReal(), E);
9868 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9873 if (!LV.isComplexInt())
9875 return Success(LV.getComplexIntImag(), E);
9879 return Success(0, E);
9882 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
9886 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
9890 bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
9900 if (!Result.isInt())
return Error(E);
9901 const APSInt &Value = Result.getInt();
9902 if (Value.isSigned() && Value.isMinSignedValue() && E->
canOverflow()) {
9905 Info.Ctx.getTypeInfo(E->
getType()).Width);
9906 Info.CCEDiag(E, diag::note_constexpr_overflow) << S << E->
getType();
9907 if (Info.noteUndefinedBehavior())
return false;
9909 return Success(-Value, E);
9915 return Success(!bres, E);
9925 class FloatExprEvaluator
9926 :
public ExprEvaluatorBase<FloatExprEvaluator> {
9929 FloatExprEvaluator(EvalInfo &info, APFloat &result)
9930 : ExprEvaluatorBaseTy(info),
Result(result) {}
9937 bool ZeroInitialization(
const Expr *E) {
9938 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
9942 bool VisitCallExpr(
const CallExpr *E);
9947 bool VisitCastExpr(
const CastExpr *E);
9958 return FloatExprEvaluator(Info, Result).Visit(E);
9965 llvm::APFloat &Result) {
9967 if (!S)
return false;
9975 fill = llvm::APInt(32, 0);
9976 else if (S->
getString().getAsInteger(0, fill))
9981 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
9983 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
9991 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
9993 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
9999 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10002 return ExprEvaluatorBaseTy::VisitCallExpr(E);
10004 case Builtin::BI__builtin_huge_val:
10005 case Builtin::BI__builtin_huge_valf:
10006 case Builtin::BI__builtin_huge_vall:
10007 case Builtin::BI__builtin_huge_valf128:
10008 case Builtin::BI__builtin_inf:
10009 case Builtin::BI__builtin_inff:
10010 case Builtin::BI__builtin_infl:
10011 case Builtin::BI__builtin_inff128: {
10012 const llvm::fltSemantics &Sem =
10013 Info.Ctx.getFloatTypeSemantics(E->
getType());
10014 Result = llvm::APFloat::getInf(Sem);
10018 case Builtin::BI__builtin_nans:
10019 case Builtin::BI__builtin_nansf:
10020 case Builtin::BI__builtin_nansl:
10021 case Builtin::BI__builtin_nansf128:
10027 case Builtin::BI__builtin_nan:
10028 case Builtin::BI__builtin_nanf:
10029 case Builtin::BI__builtin_nanl:
10030 case Builtin::BI__builtin_nanf128:
10038 case Builtin::BI__builtin_fabs:
10039 case Builtin::BI__builtin_fabsf:
10040 case Builtin::BI__builtin_fabsl:
10041 case Builtin::BI__builtin_fabsf128:
10045 if (Result.isNegative())
10046 Result.changeSign();
10053 case Builtin::BI__builtin_copysign:
10054 case Builtin::BI__builtin_copysignf:
10055 case Builtin::BI__builtin_copysignl:
10056 case Builtin::BI__builtin_copysignf128: {
10061 Result.copySign(RHS);
10067 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
10072 Result = CV.FloatReal;
10079 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
10084 Result = CV.FloatImag;
10089 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
10090 Result = llvm::APFloat::getZero(Sem);
10094 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
10096 default:
return Error(E);
10102 Result.changeSign();
10107 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10109 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10113 if (!LHSOK && !Info.noteFailure())
10119 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
10124 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10129 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10131 case CK_IntegralToFloating: {
10138 case CK_FloatingCast: {
10139 if (!Visit(SubExpr))
10145 case CK_FloatingComplexToReal: {
10149 Result = V.getComplexFloatReal();
10160 class ComplexExprEvaluator
10161 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
10165 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
10166 : ExprEvaluatorBaseTy(info),
Result(Result) {}
10173 bool ZeroInitialization(
const Expr *E);
10180 bool VisitCastExpr(
const CastExpr *E);
10190 return ComplexExprEvaluator(Info, Result).Visit(E);
10193 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
10196 Result.makeComplexFloat();
10197 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
10198 Result.FloatReal = Zero;
10199 Result.FloatImag = Zero;
10201 Result.makeComplexInt();
10202 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
10203 Result.IntReal = Zero;
10204 Result.IntImag = Zero;
10209 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
10213 Result.makeComplexFloat();
10214 APFloat &Imag = Result.FloatImag;
10218 Result.FloatReal = APFloat(Imag.getSemantics());
10222 "Unexpected imaginary literal.");
10224 Result.makeComplexInt();
10225 APSInt &Imag = Result.IntImag;
10229 Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
10234 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10238 case CK_BaseToDerived:
10239 case CK_DerivedToBase:
10240 case CK_UncheckedDerivedToBase:
10243 case CK_ArrayToPointerDecay:
10244 case CK_FunctionToPointerDecay:
10245 case CK_NullToPointer:
10246 case CK_NullToMemberPointer:
10247 case CK_BaseToDerivedMemberPointer:
10248 case CK_DerivedToBaseMemberPointer:
10249 case CK_MemberPointerToBoolean:
10250 case CK_ReinterpretMemberPointer:
10251 case CK_ConstructorConversion:
10252 case CK_IntegralToPointer:
10253 case CK_PointerToIntegral:
10254 case CK_PointerToBoolean:
10256 case CK_VectorSplat:
10257 case CK_IntegralCast:
10258 case CK_BooleanToSignedIntegral:
10259 case CK_IntegralToBoolean:
10260 case CK_IntegralToFloating:
10261 case CK_FloatingToIntegral:
10262 case CK_FloatingToBoolean:
10263 case CK_FloatingCast:
10264 case CK_CPointerToObjCPointerCast:
10265 case CK_BlockPointerToObjCPointerCast:
10266 case CK_AnyPointerToBlockPointerCast:
10267 case CK_ObjCObjectLValueCast:
10268 case CK_FloatingComplexToReal:
10269 case CK_FloatingComplexToBoolean:
10270 case CK_IntegralComplexToReal:
10271 case CK_IntegralComplexToBoolean:
10272 case CK_ARCProduceObject:
10273 case CK_ARCConsumeObject:
10274 case CK_ARCReclaimReturnedObject:
10275 case CK_ARCExtendBlockObject:
10276 case CK_CopyAndAutoreleaseBlockObject:
10277 case CK_BuiltinFnToFnPtr:
10278 case CK_ZeroToOCLOpaqueType:
10279 case CK_NonAtomicToAtomic:
10280 case CK_AddressSpaceConversion:
10281 case CK_IntToOCLSampler:
10282 case CK_FixedPointCast:
10283 case CK_FixedPointToBoolean:
10284 llvm_unreachable(
"invalid cast kind for complex value");
10286 case CK_LValueToRValue:
10287 case CK_AtomicToNonAtomic:
10289 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10292 case CK_LValueBitCast:
10293 case CK_UserDefinedConversion:
10296 case CK_FloatingRealToComplex: {
10297 APFloat &Real = Result.FloatReal;
10301 Result.makeComplexFloat();
10302 Result.FloatImag = APFloat(Real.getSemantics());
10306 case CK_FloatingComplexCast: {
10318 case CK_FloatingComplexToIntegralComplex: {
10325 Result.makeComplexInt();
10327 To, Result.IntReal) &&
10329 To, Result.IntImag);
10332 case CK_IntegralRealToComplex: {
10333 APSInt &Real = Result.IntReal;
10337 Result.makeComplexInt();
10338 Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
10342 case CK_IntegralComplexCast: {
10355 case CK_IntegralComplexToFloatingComplex: {
10362 Result.makeComplexFloat();
10364 To, Result.FloatReal) &&
10366 To, Result.FloatImag);
10370 llvm_unreachable(
"unknown cast resulting in complex value");
10373 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10375 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10379 bool LHSReal =
false, RHSReal =
false;
10384 APFloat &Real = Result.FloatReal;
10387 Result.makeComplexFloat();
10388 Result.FloatImag = APFloat(Real.getSemantics());
10391 LHSOK = Visit(E->
getLHS());
10393 if (!LHSOK && !Info.noteFailure())
10399 APFloat &Real = RHS.FloatReal;
10402 RHS.makeComplexFloat();
10403 RHS.FloatImag = APFloat(Real.getSemantics());
10407 assert(!(LHSReal && RHSReal) &&
10408 "Cannot have both operands of a complex operation be real.");
10410 default:
return Error(E);
10412 if (Result.isComplexFloat()) {
10413 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
10414 APFloat::rmNearestTiesToEven);
10416 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
10418 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
10419 APFloat::rmNearestTiesToEven);
10421 Result.getComplexIntReal() += RHS.getComplexIntReal();
10422 Result.getComplexIntImag() += RHS.getComplexIntImag();
10426 if (Result.isComplexFloat()) {
10427 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
10428 APFloat::rmNearestTiesToEven);
10430 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
10431 Result.getComplexFloatImag().changeSign();
10432 }
else if (!RHSReal) {
10433 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
10434 APFloat::rmNearestTiesToEven);
10437 Result.getComplexIntReal() -= RHS.getComplexIntReal();
10438 Result.getComplexIntImag() -= RHS.getComplexIntImag();
10442 if (Result.isComplexFloat()) {
10447 ComplexValue LHS =
Result;
10448 APFloat &A = LHS.getComplexFloatReal();
10449 APFloat &B = LHS.getComplexFloatImag();
10450 APFloat &
C = RHS.getComplexFloatReal();
10451 APFloat &D = RHS.getComplexFloatImag();
10452 APFloat &ResR = Result.getComplexFloatReal();
10453 APFloat &ResI = Result.getComplexFloatImag();
10455 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
10458 }
else if (RHSReal) {
10464 APFloat AC = A *
C;
10465 APFloat BD = B * D;
10466 APFloat AD = A * D;
10467 APFloat BC = B *
C;
10470 if (ResR.isNaN() && ResI.isNaN()) {
10471 bool Recalc =
false;
10472 if (A.isInfinity() || B.isInfinity()) {
10473 A = APFloat::copySign(
10474 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
10475 B = APFloat::copySign(
10476 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
10478 C = APFloat::copySign(APFloat(C.getSemantics()), C);
10480 D = APFloat::copySign(APFloat(D.getSemantics()), D);
10483 if (C.isInfinity() || D.isInfinity()) {
10484 C = APFloat::copySign(
10485 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
10486 D = APFloat::copySign(
10487 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
10489 A = APFloat::copySign(APFloat(A.getSemantics()), A);
10491 B = APFloat::copySign(APFloat(B.getSemantics()), B);
10494 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
10495 AD.isInfinity() || BC.isInfinity())) {
10497 A = APFloat::copySign(APFloat(A.getSemantics()), A);
10499 B = APFloat::copySign(APFloat(B.getSemantics()), B);
10501 C = APFloat::copySign(APFloat(C.getSemantics()), C);
10503 D = APFloat::copySign(APFloat(D.getSemantics()), D);
10507 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
10508 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
10513 ComplexValue LHS =
Result;
10514 Result.getComplexIntReal() =
10515 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
10516 LHS.getComplexIntImag() * RHS.getComplexIntImag());
10517 Result.getComplexIntImag() =
10518 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
10519 LHS.getComplexIntImag() * RHS.getComplexIntReal());
10523 if (Result.isComplexFloat()) {
10528 ComplexValue LHS =
Result;
10529 APFloat &A = LHS.getComplexFloatReal();
10530 APFloat &B = LHS.getComplexFloatImag();
10531 APFloat &
C = RHS.getComplexFloatReal();
10532 APFloat &D = RHS.getComplexFloatImag();
10533 APFloat &ResR = Result.getComplexFloatReal();
10534 APFloat &ResI = Result.getComplexFloatImag();
10541 B = APFloat::getZero(A.getSemantics());
10544 APFloat MaxCD = maxnum(
abs(C),
abs(D));
10545 if (MaxCD.isFinite()) {
10546 DenomLogB =
ilogb(MaxCD);
10547 C =
scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
10548 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
10550 APFloat Denom = C * C + D * D;
10551 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB,
10552 APFloat::rmNearestTiesToEven);
10553 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB,
10554 APFloat::rmNearestTiesToEven);
10555 if (ResR.isNaN() && ResI.isNaN()) {
10556 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
10557 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
10558 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
10559 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
10561 A = APFloat::copySign(
10562 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
10563 B = APFloat::copySign(
10564 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
10565 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
10566 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
10567 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
10568 C = APFloat::copySign(
10569 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
10570 D = APFloat::copySign(
10571 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
10572 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
10573 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
10578 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
10579 return Error(E, diag::note_expr_divide_by_zero);
10581 ComplexValue LHS =
Result;
10582 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
10583 RHS.getComplexIntImag() * RHS.getComplexIntImag();
10584 Result.getComplexIntReal() =
10585 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
10586 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
10587 Result.getComplexIntImag() =
10588 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
10589 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
10597 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
10611 if (Result.isComplexFloat()) {
10612 Result.getComplexFloatReal().changeSign();
10613 Result.getComplexFloatImag().changeSign();
10616 Result.getComplexIntReal() = -Result.getComplexIntReal();
10617 Result.getComplexIntImag() = -Result.getComplexIntImag();
10621 if (Result.isComplexFloat())
10622 Result.getComplexFloatImag().changeSign();
10624 Result.getComplexIntImag() = -Result.getComplexIntImag();
10629 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10632 Result.makeComplexFloat();
10638 Result.makeComplexInt();
10646 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
10655 class AtomicExprEvaluator :
10656 public ExprEvaluatorBase<AtomicExprEvaluator> {
10657 const LValue *This;
10660 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
10661 : ExprEvaluatorBaseTy(Info), This(This),
Result(Result) {}
10668 bool ZeroInitialization(
const Expr *E) {
10677 bool VisitCastExpr(
const CastExpr *E) {
10680 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10681 case CK_NonAtomicToAtomic:
10692 return AtomicExprEvaluator(Info, This, Result).Visit(E);
10701 class VoidExprEvaluator
10702 :
public ExprEvaluatorBase<VoidExprEvaluator> {
10704 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
10706 bool Success(
const APValue &V,
const Expr *e) {
return true; }
10708 bool ZeroInitialization(
const Expr *E) {
return true; }
10710 bool VisitCastExpr(
const CastExpr *E) {
10713 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10720 bool VisitCallExpr(
const CallExpr *E) {
10723 return ExprEvaluatorBaseTy::VisitCallExpr(E);
10724 case Builtin::BI__assume:
10725 case Builtin::BI__builtin_assume:
10735 return VoidExprEvaluator(Info).Visit(E);
10750 LV.moveInto(Result);
10755 if (!IntExprEvaluator(Info, Result).Visit(E))
10761 LV.moveInto(Result);
10763 llvm::APFloat F(0.0);
10771 C.moveInto(Result);
10773 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
10778 P.moveInto(Result);
10793 if (!Info.getLangOpts().CPlusPlus11)
10794 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
10809 }
else if (Info.getLangOpts().CPlusPlus11) {
10810 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
10813 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
10824 const Expr *E,
bool AllowNonLiteralTypes) {
10863 LV.setFrom(Info.Ctx, Result);
10878 L->getType()->isUnsignedIntegerType()));
10937 bool InConstantContext)
const {
10938 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
10939 Info.InConstantContext = InConstantContext;
10952 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
10958 if (!getType()->isRealFloatingType())
10966 Result = ExprResult.Val.getFloat();
10971 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
10980 LV.moveInto(Result.Val);
10986 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
10987 EvalInfo Info(Ctx, Result, EM);
10988 if (!::
Evaluate(Result.Val, Info,
this))
11000 if (isRValue() && (getType()->isArrayType() || getType()->
isRecordType()) &&
11005 EStatus.
Diag = &Notes;
11007 EvalInfo InitInfo(Ctx, EStatus, VD->
isConstexpr()
11008 ? EvalInfo::EM_ConstantExpression
11009 : EvalInfo::EM_ConstantFold);
11010 InitInfo.setEvaluatingDecl(VD, Value);
11011 InitInfo.InConstantContext =
true;
11048 EVResult.Diag =
Diag;
11049 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
11050 Info.InConstantContext =
true;
11054 assert(Result &&
"Could not evaluate expression");
11055 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
11057 return EVResult.Val.getInt();
11063 EVResult.Diag =
Diag;
11064 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
11065 Info.InConstantContext =
true;
11069 assert(Result &&
"Could not evaluate expression");
11070 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
11072 return EVResult.Val.getInt();
11079 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
11085 assert(Val.isLValue());
11113 IK_ICEIfUnevaluated,
11129 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
11134 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
11136 Info.InConstantContext =
true;
11145 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
11150 #define ABSTRACT_STMT(Node) 11151 #define STMT(Node, Base) case Expr::Node##Class: 11152 #define EXPR(Node, Base) 11153 #include "clang/AST/StmtNodes.inc" 11154 case Expr::PredefinedExprClass:
11155 case Expr::FloatingLiteralClass:
11156 case Expr::ImaginaryLiteralClass:
11157 case Expr::StringLiteralClass:
11158 case Expr::ArraySubscriptExprClass:
11159 case Expr::OMPArraySectionExprClass:
11160 case Expr::MemberExprClass:
11161 case Expr::CompoundAssignOperatorClass:
11162 case Expr::CompoundLiteralExprClass:
11163 case Expr::ExtVectorElementExprClass:
11164 case Expr::DesignatedInitExprClass:
11165 case Expr::ArrayInitLoopExprClass:
11166 case Expr::ArrayInitIndexExprClass:
11167 case Expr::NoInitExprClass:
11168 case Expr::DesignatedInitUpdateExprClass:
11169 case Expr::ImplicitValueInitExprClass:
11170 case Expr::ParenListExprClass:
11171 case Expr::VAArgExprClass:
11172 case Expr::AddrLabelExprClass:
11173 case Expr::StmtExprClass:
11174 case Expr::CXXMemberCallExprClass:
11175 case Expr::CUDAKernelCallExprClass:
11176 case Expr::CXXDynamicCastExprClass:
11177 case Expr::CXXTypeidExprClass:
11178 case Expr::CXXUuidofExprClass:
11179 case Expr::MSPropertyRefExprClass:
11180 case Expr::MSPropertySubscriptExprClass:
11181 case Expr::CXXNullPtrLiteralExprClass:
11182 case Expr::UserDefinedLiteralClass:
11183 case Expr::CXXThisExprClass:
11184 case Expr::CXXThrowExprClass:
11185 case Expr::CXXNewExprClass:
11186 case Expr::CXXDeleteExprClass:
11187 case Expr::CXXPseudoDestructorExprClass:
11188 case Expr::UnresolvedLookupExprClass:
11189 case Expr::TypoExprClass:
11190 case Expr::DependentScopeDeclRefExprClass:
11191 case Expr::CXXConstructExprClass:
11192 case Expr::CXXInheritedCtorInitExprClass:
11193 case Expr::CXXStdInitializerListExprClass:
11194 case Expr::CXXBindTemporaryExprClass:
11195 case Expr::ExprWithCleanupsClass:
11196 case Expr::CXXTemporaryObjectExprClass:
11197 case Expr::CXXUnresolvedConstructExprClass:
11198 case Expr::CXXDependentScopeMemberExprClass:
11199 case Expr::UnresolvedMemberExprClass:
11200 case Expr::ObjCStringLiteralClass:
11201 case Expr::ObjCBoxedExprClass:
11202 case Expr::ObjCArrayLiteralClass:
11203 case Expr::ObjCDictionaryLiteralClass:
11204 case Expr::ObjCEncodeExprClass:
11205 case Expr::ObjCMessageExprClass:
11206 case Expr::ObjCSelectorExprClass:
11207 case Expr::ObjCProtocolExprClass:
11208 case Expr::ObjCIvarRefExprClass:
11209 case Expr::ObjCPropertyRefExprClass:
11210 case Expr::ObjCSubscriptRefExprClass:
11211 case Expr::ObjCIsaExprClass:
11212 case Expr::ObjCAvailabilityCheckExprClass:
11213 case Expr::ShuffleVectorExprClass:
11214 case Expr::ConvertVectorExprClass:
11215 case Expr::BlockExprClass:
11217 case Expr::OpaqueValueExprClass:
11218 case Expr::PackExpansionExprClass:
11219 case Expr::SubstNonTypeTemplateParmPackExprClass:
11220 case Expr::FunctionParmPackExprClass:
11221 case Expr::AsTypeExprClass:
11222 case Expr::ObjCIndirectCopyRestoreExprClass:
11223 case Expr::MaterializeTemporaryExprClass:
11224 case Expr::PseudoObjectExprClass:
11225 case Expr::AtomicExprClass:
11226 case Expr::LambdaExprClass:
11227 case Expr::CXXFoldExprClass:
11228 case Expr::CoawaitExprClass:
11229 case Expr::DependentCoawaitExprClass:
11230 case Expr::CoyieldExprClass:
11233 case Expr::InitListExprClass: {
11239 if (cast<InitListExpr>(E)->getNumInits() == 1)
11240 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
11244 case Expr::SizeOfPackExprClass:
11245 case Expr::GNUNullExprClass:
11249 case Expr::SubstNonTypeTemplateParmExprClass:
11251 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
11253 case Expr::ConstantExprClass:
11254 return CheckICE(cast<ConstantExpr>(E)->getSubExpr(), Ctx);
11256 case Expr::ParenExprClass:
11257 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
11258 case Expr::GenericSelectionExprClass:
11259 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
11260 case Expr::IntegerLiteralClass:
11261 case Expr::FixedPointLiteralClass:
11262 case Expr::CharacterLiteralClass:
11263 case Expr::ObjCBoolLiteralExprClass:
11264 case Expr::CXXBoolLiteralExprClass:
11265 case Expr::CXXScalarValueInitExprClass:
11266 case Expr::TypeTraitExprClass:
11267 case Expr::ArrayTypeTraitExprClass:
11268 case Expr::ExpressionTraitExprClass:
11269 case Expr::CXXNoexceptExprClass:
11271 case Expr::CallExprClass:
11272 case Expr::CXXOperatorCallExprClass: {
11276 const CallExpr *CE = cast<CallExpr>(E);
11281 case Expr::DeclRefExprClass: {
11282 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
11284 const ValueDecl *D = cast<DeclRefExpr>(E)->getDecl();
11290 if (isa<ParmVarDecl>(D))
11291 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
11296 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
11297 if (!Dcl->getType()->isIntegralOrEnumerationType())
11298 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
11306 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
11311 case Expr::UnaryOperatorClass: {
11334 llvm_unreachable(
"invalid unary operator class");
11336 case Expr::OffsetOfExprClass: {
11345 case Expr::UnaryExprOrTypeTraitExprClass: {
11352 case Expr::BinaryOperatorClass: {
11397 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
11400 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
11401 if (REval.isSigned() && REval.isAllOnesValue()) {
11403 if (LEval.isMinSignedValue())
11404 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
11412 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
11413 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
11419 return Worst(LHSResult, RHSResult);
11425 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
11435 return Worst(LHSResult, RHSResult);
11438 llvm_unreachable(
"invalid binary operator kind");
11440 case Expr::ImplicitCastExprClass:
11441 case Expr::CStyleCastExprClass:
11442 case Expr::CXXFunctionalCastExprClass:
11443 case Expr::CXXStaticCastExprClass:
11444 case Expr::CXXReinterpretCastExprClass:
11445 case Expr::CXXConstCastExprClass:
11446 case Expr::ObjCBridgedCastExprClass: {
11447 const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
11448 if (isa<ExplicitCastExpr>(E)) {
11453 APSInt IgnoredVal(DestWidth, !DestSigned);
11458 if (FL->getValue().convertToInteger(IgnoredVal,
11459 llvm::APFloat::rmTowardZero,
11460 &Ignored) & APFloat::opInvalidOp)
11465 switch (cast<CastExpr>(E)->getCastKind()) {
11466 case CK_LValueToRValue:
11467 case CK_AtomicToNonAtomic:
11468 case CK_NonAtomicToAtomic:
11470 case CK_IntegralToBoolean:
11471 case CK_IntegralCast:
11477 case Expr::BinaryConditionalOperatorClass: {
11480 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
11482 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
11483 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
11484 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
11486 return FalseResult;
11488 case Expr::ConditionalOperatorClass: {
11496 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
11499 if (CondResult.Kind == IK_NotICE)
11505 if (TrueResult.Kind == IK_NotICE)
11507 if (FalseResult.Kind == IK_NotICE)
11508 return FalseResult;
11509 if (CondResult.Kind == IK_ICEIfUnevaluated)
11511 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
11517 return FalseResult;
11520 case Expr::CXXDefaultArgExprClass:
11521 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
11522 case Expr::CXXDefaultInitExprClass:
11523 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
11524 case Expr::ChooseExprClass: {
11525 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
11529 llvm_unreachable(
"Invalid StmtClass!");
11535 llvm::APSInt *Value,
11546 if (!Result.
isInt()) {
11551 if (Value) *Value = Result.
getInt();
11561 if (D.Kind != IK_ICE) {
11562 if (Loc) *Loc = D.Loc;
11573 if (!isIntegerConstantExpr(Ctx, Loc))
11582 EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
11583 Info.InConstantContext =
true;
11585 if (!::
EvaluateAsInt(
this, ExprResult, Ctx, SE_AllowSideEffects, Info))
11586 llvm_unreachable(
"ICE cannot be evaluated!");
11588 Value = ExprResult.Val.getInt();
11593 return CheckICE(
this, Ctx).Kind == IK_ICE;
11605 Status.Diag = &Diags;
11606 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
11611 if (!Diags.empty()) {
11612 IsConstExpr =
false;
11613 if (Loc) *Loc = Diags[0].first;
11614 }
else if (!IsConstExpr) {
11616 if (Loc) *Loc = getExprLoc();
11619 return IsConstExpr;
11625 const Expr *This)
const {
11627 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
11630 const LValue *ThisPtr =
nullptr;
11634 assert(MD &&
"Don't provide `this` for non-methods.");
11635 assert(!MD->isStatic() &&
"Don't provide `this` for static methods.");
11638 ThisPtr = &ThisVal;
11639 if (Info.EvalStatus.HasSideEffects)
11643 ArgVector ArgValues(Args.size());
11646 if ((*I)->isValueDependent() ||
11647 !
Evaluate(ArgValues[I - Args.begin()], Info, *I))
11649 ArgValues[I - Args.begin()] =
APValue();
11650 if (Info.EvalStatus.HasSideEffects)
11655 CallStackFrame Frame(Info, Callee->
getLocation(), Callee, ThisPtr,
11657 return Evaluate(Value, Info,
this) && !Info.EvalStatus.HasSideEffects;
11670 Status.
Diag = &Diags;
11673 EvalInfo::EM_PotentialConstantExpression);
11674 Info.InConstantContext =
true;
11683 This.set({&VIE, Info.CurrentCall->Index});
11691 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
11696 Args, FD->
getBody(), Info, Scratch,
nullptr);
11699 return Diags.empty();
11707 Status.
Diag = &Diags;
11710 EvalInfo::EM_PotentialConstantExpressionUnevaluated);
11714 ArgVector ArgValues(0);
11718 "Failed to set up arguments for potential constant evaluation");
11719 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
11723 return Diags.empty();
11727 unsigned Type)
const {
11728 if (!getType()->isPointerType())
11732 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
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 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.
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
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.
CompoundStmt * getSubStmt()
const Expr * getInit(unsigned Init) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
Stmt - This represents one statement.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
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.
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.
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
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)
void * BaseOrMember
BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item in the path.
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
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
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.
const Expr * getResultExpr() const
The generic selection's result expression.
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...
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...
ArrayRef< LValuePathEntry > getLValuePath() 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.
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
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
Represents a struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
unsigned getVersion() const
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.
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 getCallIndex() const
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.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
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.
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...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
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.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
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)
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 isRecordType(QualType T)
std::string getAsString(ASTContext &Ctx, QualType Ty) const
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage=Expr::EvaluateForCodeGen)
Check that this core constant expression value is a valid value for a constant expression.
bool isComplexFloat() const
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.
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
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
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
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.
bool isUnsignedFixedPointType() const
Return true if this is a fixed point type that is unsigned according to ISO/IEC JTC1 SC22 WG14 N1169...
Represents the this expression in C++.
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)
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 ...
ConditionalOperator - The ?: ternary operator.
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...
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
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.
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.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ConstantExpr - An expression that occurs in a constant context.
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...
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.
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.
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 bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
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.
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)
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()
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)
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.
bool isSignedFixedPointType() const
Return true if this is a fixed point type that is signed according to ISO/IEC JTC1 SC22 WG14 N1169...
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
bool isVoidPointerType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
RecordDecl * getDecl() const
static 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)
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...
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
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.
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()
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)
void FixedPointValueToString(SmallVectorImpl< char > &Str, llvm::APSInt Val, unsigned Scale)
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.
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...
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)
An expression trait intrinsic.
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;}).
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
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)
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.
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;...
Dataflow Directional Tag Classes.
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
Returns 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
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.
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).
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
llvm::APInt getValue() const
LabelDecl * getLabel() const
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
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)
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...
static bool EvaluateArgs(ArrayRef< const Expr *> Args, ArgVector &ArgValues, EvalInfo &Info)
EvaluateArgs - Evaluate the arguments to a function call.
A use of a default initializer in a constructor or in aggregate initialization.
A template argument list.
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.
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.
static bool EvaluateBuiltinConstantPForLValue(const LValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
ActionResult< Expr * > ExprResult
bool hasUnaligned() const
APFloat & getComplexFloatImag()
Represents a C++ struct/union/class.
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.
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
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...
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]).
static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage...
__DEVICE__ int max(int __a, int __b)
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
__DEVICE__ int min(int __a, int __b)
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.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static void expandStringLiteral(EvalInfo &Info, const Expr *Lit, APValue &Result)
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 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)
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).
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Automatic storage duration (most local variables).
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.
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.
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
IgnoreParens - Ignore parentheses.
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 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