47 #include "llvm/Support/raw_ostream.h"
51 using namespace clang;
59 struct CallStackFrame;
72 dyn_cast<MaterializeTemporaryExpr>(Base)) {
75 const Expr *Temp = MTE->GetTemporaryExpr();
80 if (!Adjustments.empty())
99 return dyn_cast<
FieldDecl>(getAsBaseOrMember(E).getPointer());
104 return dyn_cast<
CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
109 return getAsBaseOrMember(E).getInt();
113 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
115 return Callee ? Callee->
getAttr<AllocSizeAttr>() :
nullptr;
122 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
129 if (
const auto *Cast = dyn_cast<CastExpr>(E))
132 if (
const auto *CE = dyn_cast<CallExpr>(E))
133 return getAllocSizeAttr(CE) ? CE :
nullptr;
140 const auto *E = Base.dyn_cast<
const Expr *>();
154 assert(!isBaseAnAllocSizeCall(Base) &&
155 "Unsized arrays shouldn't appear here");
156 unsigned MostDerivedLength = 0;
157 Type = getType(Base);
159 for (
unsigned I = 0, N = Path.size();
I != N; ++
I) {
164 ArraySize = CAT->
getSize().getZExtValue();
165 MostDerivedLength =
I + 1;
167 }
else if (Type->isAnyComplexType()) {
171 MostDerivedLength =
I + 1;
173 }
else if (
const FieldDecl *FD = getAsField(Path[
I])) {
174 Type = FD->getType();
176 MostDerivedLength = I + 1;
184 return MostDerivedLength;
189 CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex,
190 CSK_This, CSK_Real, CSK_Imag
194 struct SubobjectDesignator {
201 unsigned IsOnePastTheEnd : 1;
204 unsigned FirstEntryIsAnUnsizedArray : 1;
207 unsigned MostDerivedIsArrayElement : 1;
211 unsigned MostDerivedPathLength : 28;
220 uint64_t MostDerivedArraySize;
232 explicit SubobjectDesignator(
QualType T)
234 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
235 MostDerivedPathLength(0), MostDerivedArraySize(0),
236 MostDerivedType(T) {}
239 :
Invalid(!V.isLValue() || !V.hasLValuePath()), IsOnePastTheEnd(
false),
240 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
241 MostDerivedPathLength(0), MostDerivedArraySize(0) {
242 assert(V.
isLValue() &&
"Non-LValue used to make an LValue designator?");
246 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
248 bool IsArray =
false;
249 MostDerivedPathLength = findMostDerivedSubobject(
251 MostDerivedType, IsArray);
252 MostDerivedIsArrayElement = IsArray;
264 bool isMostDerivedAnUnsizedArray()
const {
265 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
266 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
271 uint64_t getMostDerivedArraySize()
const {
272 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
273 return MostDerivedArraySize;
277 bool isOnePastTheEnd()
const {
281 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
282 Entries[MostDerivedPathLength - 1].ArrayIndex == MostDerivedArraySize)
288 bool isValidSubobject()
const {
291 return !isOnePastTheEnd();
300 Entry.ArrayIndex = 0;
301 Entries.push_back(Entry);
305 MostDerivedIsArrayElement =
true;
306 MostDerivedArraySize = CAT->
getSize().getZExtValue();
307 MostDerivedPathLength = Entries.size();
311 void addUnsizedArrayUnchecked(
QualType ElemTy) {
313 Entry.ArrayIndex = 0;
314 Entries.push_back(Entry);
316 MostDerivedType = ElemTy;
317 MostDerivedIsArrayElement =
true;
322 MostDerivedPathLength = Entries.size();
326 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
329 Entry.BaseOrMember = Value.getOpaqueValue();
330 Entries.push_back(Entry);
333 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
334 MostDerivedType = FD->getType();
335 MostDerivedIsArrayElement =
false;
336 MostDerivedArraySize = 0;
337 MostDerivedPathLength = Entries.size();
341 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
343 Entry.ArrayIndex = Imag;
344 Entries.push_back(Entry);
348 MostDerivedType = EltTy;
349 MostDerivedIsArrayElement =
true;
350 MostDerivedArraySize = 2;
351 MostDerivedPathLength = Entries.size();
353 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
356 void adjustIndex(EvalInfo &Info,
const Expr *E, APSInt N) {
357 if (Invalid || !N)
return;
358 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
359 if (isMostDerivedAnUnsizedArray()) {
363 Entries.back().ArrayIndex += TruncatedN;
370 bool IsArray = MostDerivedPathLength == Entries.size() &&
371 MostDerivedIsArrayElement;
372 uint64_t ArrayIndex =
373 IsArray ? Entries.back().ArrayIndex : (uint64_t)IsOnePastTheEnd;
375 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
377 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
380 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
381 (llvm::APInt&)N += ArrayIndex;
382 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
383 diagnosePointerArithmetic(Info, E, N);
388 ArrayIndex += TruncatedN;
389 assert(ArrayIndex <= ArraySize &&
390 "bounds check succeeded for out-of-bounds index");
393 Entries.back().ArrayIndex = ArrayIndex;
395 IsOnePastTheEnd = (ArrayIndex != 0);
400 struct CallStackFrame {
404 CallStackFrame *Caller;
418 typedef std::map<const void*, APValue>
MapTy;
419 typedef MapTy::const_iterator temp_iterator;
437 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
445 APValue *getTemporary(
const void *Key) {
446 MapTy::iterator
I = Temporaries.find(Key);
447 return I == Temporaries.end() ?
nullptr : &I->second;
449 APValue &createTemporary(
const void *Key,
bool IsLifetimeExtended);
453 class ThisOverrideRAII {
455 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
456 : Frame(Frame), OldThis(Frame.This) {
458 Frame.This = NewThis;
460 ~ThisOverrideRAII() {
461 Frame.This = OldThis;
464 CallStackFrame &Frame;
465 const LValue *OldThis;
470 class OptionalDiagnostic {
484 OptionalDiagnostic &
operator<<(
const APSInt &I) {
488 *
Diag << StringRef(Buffer.data(), Buffer.size());
493 OptionalDiagnostic &
operator<<(
const APFloat &F) {
502 llvm::APFloat::semanticsPrecision(F.getSemantics());
503 precision = (precision * 59 + 195) / 196;
505 F.toString(Buffer, precision);
506 *
Diag << StringRef(Buffer.data(), Buffer.size());
514 llvm::PointerIntPair<APValue*, 1, bool>
Value;
517 Cleanup(
APValue *Val,
bool IsLifetimeExtended)
518 : Value(Val, IsLifetimeExtended) {}
520 bool isLifetimeExtended()
const {
return Value.getInt(); }
522 *Value.getPointer() =
APValue();
540 struct LLVM_ALIGNAS( 8) EvalInfo {
547 CallStackFrame *CurrentCall;
550 unsigned CallStackDepth;
553 unsigned NextCallIndex;
562 CallStackFrame BottomFrame;
578 uint64_t ArrayInitIndex = -1;
582 bool HasActiveDiagnostic;
586 bool HasFoldFailureDiagnostic;
589 bool IsSpeculativelyEvaluating;
591 enum EvaluationMode {
594 EM_ConstantExpression,
600 EM_PotentialConstantExpression,
609 EM_EvaluateForOverflow,
613 EM_IgnoreSideEffects,
620 EM_ConstantExpressionUnevaluated,
629 EM_PotentialConstantExpressionUnevaluated,
646 bool checkingPotentialConstantExpression()
const {
647 return EvalMode == EM_PotentialConstantExpression ||
648 EvalMode == EM_PotentialConstantExpressionUnevaluated;
654 bool checkingForOverflow() {
return EvalMode == EM_EvaluateForOverflow; }
657 : Ctx(const_cast<
ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
658 CallStackDepth(0), NextCallIndex(1),
659 StepsLeft(getLangOpts().ConstexprStepLimit),
661 EvaluatingDecl((const
ValueDecl *)nullptr),
662 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
663 HasFoldFailureDiagnostic(
false), IsSpeculativelyEvaluating(
false),
667 EvaluatingDecl = Base;
668 EvaluatingDeclValue = &
Value;
676 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
678 if (NextCallIndex == 0) {
680 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
683 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
685 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
686 << getLangOpts().ConstexprCallDepth;
690 CallStackFrame *getCallFrame(
unsigned CallIndex) {
691 assert(CallIndex &&
"no call index in getCallFrame");
694 CallStackFrame *Frame = CurrentCall;
695 while (Frame->Index > CallIndex)
696 Frame = Frame->Caller;
697 return (Frame->Index == CallIndex) ? Frame :
nullptr;
700 bool nextStep(
const Stmt *
S) {
702 FFDiag(S->
getLocStart(), diag::note_constexpr_step_limit_exceeded);
713 EvalStatus.Diag->push_back(std::make_pair(Loc, PD));
714 return EvalStatus.Diag->back().second;
718 void addCallStack(
unsigned Limit);
722 unsigned ExtraNotes,
bool IsCCEDiag) {
724 if (EvalStatus.Diag) {
731 if (!EvalStatus.Diag->empty()) {
733 case EM_ConstantFold:
734 case EM_IgnoreSideEffects:
735 case EM_EvaluateForOverflow:
736 if (!HasFoldFailureDiagnostic)
740 case EM_ConstantExpression:
741 case EM_PotentialConstantExpression:
742 case EM_ConstantExpressionUnevaluated:
743 case EM_PotentialConstantExpressionUnevaluated:
745 HasActiveDiagnostic =
false;
746 return OptionalDiagnostic();
750 unsigned CallStackNotes = CallStackDepth - 1;
753 CallStackNotes =
std::min(CallStackNotes, Limit + 1);
754 if (checkingPotentialConstantExpression())
757 HasActiveDiagnostic =
true;
758 HasFoldFailureDiagnostic = !IsCCEDiag;
759 EvalStatus.Diag->clear();
760 EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
761 addDiag(Loc, DiagId);
762 if (!checkingPotentialConstantExpression())
764 return OptionalDiagnostic(&(*EvalStatus.Diag)[0].second);
766 HasActiveDiagnostic =
false;
767 return OptionalDiagnostic();
773 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
774 unsigned ExtraNotes = 0) {
775 return Diag(Loc, DiagId, ExtraNotes,
false);
779 = diag::note_invalid_subexpr_in_const_expr,
780 unsigned ExtraNotes = 0) {
783 HasActiveDiagnostic =
false;
784 return OptionalDiagnostic();
793 = diag::note_invalid_subexpr_in_const_expr,
794 unsigned ExtraNotes = 0) {
797 if (!EvalStatus.Diag || !EvalStatus.Diag->empty()) {
798 HasActiveDiagnostic =
false;
799 return OptionalDiagnostic();
801 return Diag(Loc, DiagId, ExtraNotes,
true);
804 = diag::note_invalid_subexpr_in_const_expr,
805 unsigned ExtraNotes = 0) {
806 return CCEDiag(E->
getExprLoc(), DiagId, ExtraNotes);
810 if (!HasActiveDiagnostic)
811 return OptionalDiagnostic();
812 return OptionalDiagnostic(&addDiag(Loc, DiagId));
817 if (HasActiveDiagnostic) {
818 EvalStatus.Diag->insert(EvalStatus.Diag->end(),
819 Diags.begin(), Diags.end());
825 bool keepEvaluatingAfterSideEffect() {
827 case EM_PotentialConstantExpression:
828 case EM_PotentialConstantExpressionUnevaluated:
829 case EM_EvaluateForOverflow:
830 case EM_IgnoreSideEffects:
833 case EM_ConstantExpression:
834 case EM_ConstantExpressionUnevaluated:
835 case EM_ConstantFold:
839 llvm_unreachable(
"Missed EvalMode case");
844 bool noteSideEffect() {
845 EvalStatus.HasSideEffects =
true;
846 return keepEvaluatingAfterSideEffect();
850 bool keepEvaluatingAfterUndefinedBehavior() {
852 case EM_EvaluateForOverflow:
853 case EM_IgnoreSideEffects:
854 case EM_ConstantFold:
858 case EM_PotentialConstantExpression:
859 case EM_PotentialConstantExpressionUnevaluated:
860 case EM_ConstantExpression:
861 case EM_ConstantExpressionUnevaluated:
864 llvm_unreachable(
"Missed EvalMode case");
870 bool noteUndefinedBehavior() {
871 EvalStatus.HasUndefinedBehavior =
true;
872 return keepEvaluatingAfterUndefinedBehavior();
877 bool keepEvaluatingAfterFailure() {
882 case EM_PotentialConstantExpression:
883 case EM_PotentialConstantExpressionUnevaluated:
884 case EM_EvaluateForOverflow:
887 case EM_ConstantExpression:
888 case EM_ConstantExpressionUnevaluated:
889 case EM_ConstantFold:
890 case EM_IgnoreSideEffects:
894 llvm_unreachable(
"Missed EvalMode case");
907 LLVM_NODISCARD
bool noteFailure() {
915 bool KeepGoing = keepEvaluatingAfterFailure();
916 EvalStatus.HasSideEffects |= KeepGoing;
920 class ArrayInitLoopIndex {
925 ArrayInitLoopIndex(EvalInfo &Info)
926 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
927 Info.ArrayInitIndex = 0;
929 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
931 operator uint64_t&() {
return Info.ArrayInitIndex; }
936 struct FoldConstant {
939 bool HadNoPriorDiags;
940 EvalInfo::EvaluationMode OldMode;
942 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
945 HadNoPriorDiags(Info.EvalStatus.
Diag &&
946 Info.EvalStatus.
Diag->empty() &&
947 !Info.EvalStatus.HasSideEffects),
948 OldMode(Info.EvalMode) {
950 (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
951 Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
952 Info.EvalMode = EvalInfo::EM_ConstantFold;
954 void keepDiagnostics() { Enabled =
false; }
956 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
957 !Info.EvalStatus.HasSideEffects)
958 Info.EvalStatus.Diag->clear();
959 Info.EvalMode = OldMode;
965 struct FoldOffsetRAII {
967 EvalInfo::EvaluationMode OldMode;
968 explicit FoldOffsetRAII(EvalInfo &Info)
969 : Info(Info), OldMode(Info.EvalMode) {
970 if (!Info.checkingPotentialConstantExpression())
971 Info.EvalMode = EvalInfo::EM_OffsetFold;
974 ~FoldOffsetRAII() { Info.EvalMode = OldMode; }
979 class SpeculativeEvaluationRAII {
982 llvm::PointerIntPair<EvalInfo *, 1, bool> InfoAndOldSpecEval;
985 void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
986 InfoAndOldSpecEval = Other.InfoAndOldSpecEval;
988 Other.InfoAndOldSpecEval.setPointer(
nullptr);
991 void maybeRestoreState() {
992 EvalInfo *Info = InfoAndOldSpecEval.getPointer();
997 Info->IsSpeculativelyEvaluating = InfoAndOldSpecEval.getInt();
1001 SpeculativeEvaluationRAII() =
default;
1003 SpeculativeEvaluationRAII(
1005 : InfoAndOldSpecEval(&Info, Info.IsSpeculativelyEvaluating),
1006 Old(Info.EvalStatus) {
1007 Info.EvalStatus.Diag = NewDiag;
1008 Info.IsSpeculativelyEvaluating =
true;
1011 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &Other) =
delete;
1012 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&Other) {
1013 moveFromAndCancel(std::move(Other));
1016 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&Other) {
1017 maybeRestoreState();
1018 moveFromAndCancel(std::move(Other));
1022 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1027 template<
bool IsFullExpression>
1030 unsigned OldStackSize;
1032 ScopeRAII(EvalInfo &Info)
1033 : Info(Info), OldStackSize(Info.CleanupStack.size()) {}
1040 static void cleanup(EvalInfo &Info,
unsigned OldStackSize) {
1041 unsigned NewEnd = OldStackSize;
1042 for (
unsigned I = OldStackSize, N = Info.CleanupStack.size();
1044 if (IsFullExpression && Info.CleanupStack[I].isLifetimeExtended()) {
1047 std::swap(Info.CleanupStack[I], Info.CleanupStack[NewEnd]);
1051 Info.CleanupStack[
I].endLifetime();
1054 Info.CleanupStack.erase(Info.CleanupStack.begin() + NewEnd,
1055 Info.CleanupStack.end());
1058 typedef ScopeRAII<false> BlockScopeRAII;
1059 typedef ScopeRAII<true> FullExpressionRAII;
1062 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1066 if (isOnePastTheEnd()) {
1067 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1075 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1080 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1081 Info.CCEDiag(E, diag::note_constexpr_array_index)
1083 <<
static_cast<unsigned>(getMostDerivedArraySize());
1085 Info.CCEDiag(E, diag::note_constexpr_array_index)
1090 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
1093 : Info(Info), Caller(Info.CurrentCall), Callee(Callee), This(This),
1094 Arguments(Arguments), CallLoc(CallLoc), Index(Info.NextCallIndex++) {
1095 Info.CurrentCall =
this;
1096 ++Info.CallStackDepth;
1099 CallStackFrame::~CallStackFrame() {
1100 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1101 --Info.CallStackDepth;
1102 Info.CurrentCall = Caller;
1105 APValue &CallStackFrame::createTemporary(
const void *Key,
1106 bool IsLifetimeExtended) {
1108 assert(Result.
isUninit() &&
"temporary created multiple times");
1109 Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
1113 static void describeCall(CallStackFrame *Frame, raw_ostream &Out);
1115 void EvalInfo::addCallStack(
unsigned Limit) {
1117 unsigned ActiveCalls = CallStackDepth - 1;
1118 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
1119 if (Limit && Limit < ActiveCalls) {
1120 SkipStart = Limit / 2 + Limit % 2;
1121 SkipEnd = ActiveCalls - Limit / 2;
1125 unsigned CallIdx = 0;
1126 for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
1127 Frame = Frame->Caller, ++CallIdx) {
1129 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
1130 if (CallIdx == SkipStart) {
1132 addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
1140 if (
auto *CD = dyn_cast_or_null<CXXConstructorDecl>(Frame->Callee)) {
1141 if (CD->isInheritingConstructor()) {
1142 addDiag(Frame->CallLoc, diag::note_constexpr_inherited_ctor_call_here)
1149 llvm::raw_svector_ostream Out(Buffer);
1151 addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
1156 struct ComplexValue {
1161 APSInt IntReal, IntImag;
1162 APFloat FloatReal, FloatImag;
1164 ComplexValue() : FloatReal(APFloat::Bogus()), FloatImag(APFloat::Bogus()) {}
1166 void makeComplexFloat() { IsInt =
false; }
1167 bool isComplexFloat()
const {
return !IsInt; }
1168 APFloat &getComplexFloatReal() {
return FloatReal; }
1169 APFloat &getComplexFloatImag() {
return FloatImag; }
1171 void makeComplexInt() { IsInt =
true; }
1172 bool isComplexInt()
const {
return IsInt; }
1173 APSInt &getComplexIntReal() {
return IntReal; }
1174 APSInt &getComplexIntImag() {
return IntImag; }
1176 void moveInto(
APValue &v)
const {
1177 if (isComplexFloat())
1178 v =
APValue(FloatReal, FloatImag);
1180 v =
APValue(IntReal, IntImag);
1182 void setFrom(
const APValue &v) {
1199 unsigned InvalidBase : 1;
1200 unsigned CallIndex : 31;
1207 unsigned getLValueCallIndex()
const {
return CallIndex; }
1208 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1209 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1210 bool isNullPointer()
const {
return IsNullPtr;}
1212 void moveInto(
APValue &V)
const {
1217 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1218 assert(!
Designator.FirstEntryIsAnUnsizedArray &&
1219 "Unsized array with a valid base?");
1221 Designator.IsOnePastTheEnd, CallIndex, IsNullPtr);
1225 assert(V.
isLValue() &&
"Setting LValue from a non-LValue?");
1228 InvalidBase =
false;
1238 const auto *E = B.get<
const Expr *>();
1239 assert((isa<MemberExpr>(E) || tryUnwrapAllocSizeCall(E)) &&
1240 "Unexpected type of invalid base");
1245 Offset = CharUnits::fromQuantity(0);
1246 InvalidBase = BInvalid;
1248 Designator = SubobjectDesignator(getType(B));
1252 void setNull(
QualType PointerTy, uint64_t TargetVal) {
1253 Base = (
Expr *)
nullptr;
1254 Offset = CharUnits::fromQuantity(TargetVal);
1255 InvalidBase =
false;
1267 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1272 Info.CCEDiag(E, diag::note_constexpr_null_subobject)
1283 return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
1287 void addDecl(EvalInfo &Info,
const Expr *E,
1288 const Decl *D,
bool Virtual =
false) {
1289 if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
1292 void addUnsizedArray(EvalInfo &Info,
QualType ElemTy) {
1293 assert(
Designator.Entries.empty() && getType(Base)->isPointerType());
1294 assert(isBaseAnAllocSizeCall(Base) &&
1295 "Only alloc_size bases can have unsized arrays");
1296 Designator.FirstEntryIsAnUnsizedArray =
true;
1300 if (checkSubobject(Info, E, CSK_ArrayToPointer))
1303 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1304 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1307 void clearIsNullPointer() {
1310 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1311 const APSInt &Index,
CharUnits ElementSize) {
1320 uint64_t Offset64 =
Offset.getQuantity();
1322 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1323 Offset = CharUnits::fromQuantity(Offset64 + ElemSize64 * Index64);
1325 if (checkNullPointer(Info, E, CSK_ArrayIndex))
1327 clearIsNullPointer();
1332 clearIsNullPointer();
1339 DeclAndIsDerivedMember(Decl,
false), Path() {}
1344 return DeclAndIsDerivedMember.getPointer();
1347 bool isDerivedMember()
const {
1348 return DeclAndIsDerivedMember.getInt();
1352 return cast<CXXRecordDecl>(
1353 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1356 void moveInto(
APValue &V)
const {
1357 V =
APValue(getDecl(), isDerivedMember(), Path);
1359 void setFrom(
const APValue &V) {
1365 Path.insert(Path.end(), P.begin(), P.end());
1371 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1379 assert(!Path.empty());
1381 if (Path.size() >= 2)
1382 Expected = Path[Path.size() - 2];
1384 Expected = getContainingRecord();
1401 if (!isDerivedMember()) {
1402 Path.push_back(Derived);
1405 if (!castBack(Derived))
1408 DeclAndIsDerivedMember.setInt(
false);
1416 DeclAndIsDerivedMember.setInt(
true);
1417 if (isDerivedMember()) {
1418 Path.push_back(Base);
1421 return castBack(Base);
1426 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1427 if (!LHS.getDecl() || !RHS.getDecl())
1428 return !LHS.getDecl() && !RHS.getDecl();
1429 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1431 return LHS.Path == RHS.Path;
1437 const LValue &This,
const Expr *E,
1438 bool AllowNonLiteralTypes =
false);
1440 bool InvalidBaseOK =
false);
1442 bool InvalidBaseOK =
false);
1462 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1463 Int = Int.extend(Int.getBitWidth() + 1);
1464 Int.setIsSigned(
true);
1471 unsigned ArgIndex = 0;
1472 bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
1473 !isa<CXXConstructorDecl>(Frame->Callee) &&
1474 cast<CXXMethodDecl>(Frame->Callee)->isInstance();
1477 Out << *Frame->Callee <<
'(';
1479 if (Frame->This && IsMemberCall) {
1481 Frame->This->moveInto(Val);
1483 Frame->This->Designator.MostDerivedType);
1485 Out <<
"->" << *Frame->Callee <<
'(';
1486 IsMemberCall =
false;
1490 E = Frame->Callee->param_end(); I !=
E; ++
I, ++ArgIndex) {
1491 if (ArgIndex > (
unsigned)IsMemberCall)
1495 const APValue &Arg = Frame->Arguments[ArgIndex];
1498 if (ArgIndex == 0 && IsMemberCall)
1499 Out <<
"->" << *Frame->Callee <<
'(';
1512 return Info.noteSideEffect();
1519 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1520 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1529 if (!B)
return true;
1533 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1534 return VD->hasGlobalStorage();
1536 return isa<FunctionDecl>(D);
1539 const Expr *E = B.get<
const Expr*>();
1543 case Expr::CompoundLiteralExprClass: {
1547 case Expr::MaterializeTemporaryExprClass:
1550 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
1552 case Expr::StringLiteralClass:
1553 case Expr::PredefinedExprClass:
1554 case Expr::ObjCStringLiteralClass:
1555 case Expr::ObjCEncodeExprClass:
1556 case Expr::CXXTypeidExprClass:
1557 case Expr::CXXUuidofExprClass:
1559 case Expr::CallExprClass:
1562 case Expr::AddrLabelExprClass:
1566 case Expr::BlockExprClass:
1567 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
1568 case Expr::ImplicitValueInitExprClass:
1580 assert(Base &&
"no location for a null lvalue");
1583 Info.Note(VD->
getLocation(), diag::note_declared_at);
1586 diag::note_constexpr_temporary_here);
1593 QualType Type,
const LValue &LVal) {
1597 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
1603 if (Info.getLangOpts().CPlusPlus11) {
1605 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
1606 << IsReferenceType << !Designator.Entries.empty()
1615 assert((Info.checkingPotentialConstantExpression() ||
1616 LVal.getLValueCallIndex() == 0) &&
1617 "have call index for global lvalue");
1620 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
1622 if (Var->getTLSKind())
1626 if (Var->hasAttr<DLLImportAttr>())
1629 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
1640 if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
1647 if (!IsReferenceType)
1658 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
1660 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
1661 << !Designator.Entries.empty() << !!VD << VD;
1675 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
1678 return FD->isVirtual() || !FD->
hasAttr<DLLImportAttr>();
1684 const LValue *This =
nullptr) {
1701 if (This && Info.EvaluatingDecl == This->getLValueBase())
1705 if (Info.getLangOpts().CPlusPlus11)
1706 Info.FFDiag(E, diag::note_constexpr_nonliteral)
1709 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1719 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
1727 Type = AT->getValueType();
1751 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
1752 unsigned BaseIndex = 0;
1754 End = CD->bases_end(); I !=
End; ++
I, ++BaseIndex) {
1760 for (
const auto *I : RD->
fields()) {
1769 LVal.setFrom(Info.Ctx, Value);
1781 return LVal.Base.dyn_cast<
const ValueDecl*>();
1785 if (Value.CallIndex)
1787 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1788 return E && !isa<MaterializeTemporaryExpr>(
E);
1793 return Decl && Decl->
isWeak();
1798 if (Decl && isa<VarDecl>(Decl)) {
1819 return !Decl || !Decl->
isWeak();
1827 Result = Val.
getInt().getBoolValue();
1829 case APValue::Float:
1832 case APValue::ComplexInt:
1836 case APValue::ComplexFloat:
1840 case APValue::LValue:
1842 case APValue::MemberPointer:
1845 case APValue::Vector:
1846 case APValue::Array:
1847 case APValue::Struct:
1848 case APValue::Union:
1849 case APValue::AddrLabelDiff:
1853 llvm_unreachable(
"unknown APValue kind");
1858 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
1865 template<
typename T>
1867 const T &SrcValue,
QualType DestType) {
1868 Info.CCEDiag(E, diag::note_constexpr_overflow)
1869 << SrcValue << DestType;
1870 return Info.noteUndefinedBehavior();
1874 QualType SrcType,
const APFloat &Value,
1875 QualType DestType, APSInt &Result) {
1876 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1880 Result = APSInt(DestWidth, !DestSigned);
1882 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
1883 & APFloat::opInvalidOp)
1893 if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
1894 APFloat::rmNearestTiesToEven, &ignored)
1895 & APFloat::opOverflow)
1902 const APSInt &Value) {
1903 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1904 APSInt Result =
Value;
1907 Result = Result.extOrTrunc(DestWidth);
1913 QualType SrcType,
const APSInt &Value,
1914 QualType DestType, APFloat &Result) {
1915 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
1916 if (Result.convertFromAPInt(Value, Value.isSigned(),
1917 APFloat::rmNearestTiesToEven)
1918 & APFloat::opOverflow)
1925 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
1927 if (!Value.
isInt()) {
1931 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
1936 APSInt &Int = Value.
getInt();
1937 unsigned OldBitWidth = Int.getBitWidth();
1939 if (NewBitWidth < OldBitWidth)
1940 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
1954 Res = SVal.
getFloat().bitcastToAPInt();
1959 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
1961 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
1962 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
1963 Res = llvm::APInt::getNullValue(VecSize);
1966 llvm::APInt EltAsInt;
1970 EltAsInt = Elt.
getFloat().bitcastToAPInt();
1974 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1977 unsigned BaseEltSize = EltAsInt.getBitWidth();
1979 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(i*EltSize+BaseEltSize);
1981 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(i*EltSize);
1987 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1994 template<
typename Operation>
1996 const APSInt &LHS,
const APSInt &RHS,
1997 unsigned BitWidth, Operation Op,
1999 if (LHS.isUnsigned()) {
2000 Result = Op(LHS, RHS);
2004 APSInt
Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2005 Result = Value.trunc(LHS.getBitWidth());
2006 if (Result.extend(BitWidth) !=
Value) {
2007 if (Info.checkingForOverflow())
2008 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2009 diag::warn_integer_constant_overflow)
2010 << Result.toString(10) << E->
getType();
2027 std::multiplies<APSInt>(), Result);
2030 std::plus<APSInt>(), Result);
2033 std::minus<APSInt>(), Result);
2034 case BO_And: Result = LHS & RHS;
return true;
2035 case BO_Xor: Result = LHS ^ RHS;
return true;
2036 case BO_Or: Result = LHS | RHS;
return true;
2040 Info.FFDiag(E, diag::note_expr_divide_by_zero);
2043 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2046 if (RHS.isNegative() && RHS.isAllOnesValue() &&
2047 LHS.isSigned() && LHS.isMinSignedValue())
2048 return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
2052 if (Info.getLangOpts().OpenCL)
2054 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2055 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2057 else if (RHS.isSigned() && RHS.isNegative()) {
2060 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2067 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2069 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2070 << RHS << E->
getType() << LHS.getBitWidth();
2071 }
else if (LHS.isSigned()) {
2074 if (LHS.isNegative())
2075 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2076 else if (LHS.countLeadingZeros() < SA)
2077 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2083 if (Info.getLangOpts().OpenCL)
2085 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2086 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2088 else if (RHS.isSigned() && RHS.isNegative()) {
2091 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2098 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2100 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2101 << RHS << E->
getType() << LHS.getBitWidth();
2106 case BO_LT: Result = LHS < RHS;
return true;
2107 case BO_GT: Result = LHS > RHS;
return true;
2108 case BO_LE: Result = LHS <= RHS;
return true;
2109 case BO_GE: Result = LHS >= RHS;
return true;
2110 case BO_EQ: Result = LHS == RHS;
return true;
2111 case BO_NE: Result = LHS != RHS;
return true;
2118 const APFloat &RHS) {
2124 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
2127 LHS.add(RHS, APFloat::rmNearestTiesToEven);
2130 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
2133 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
2137 if (LHS.isInfinity() || LHS.isNaN()) {
2138 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2139 return Info.noteUndefinedBehavior();
2148 unsigned TruncatedElements) {
2149 SubobjectDesignator &D = Result.Designator;
2152 if (TruncatedElements == D.Entries.size())
2154 assert(TruncatedElements >= D.MostDerivedPathLength &&
2155 "not casting to a derived class");
2156 if (!Result.checkSubobject(Info, E, CSK_Derived))
2161 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++
I) {
2165 if (isVirtualBaseClass(D.Entries[I]))
2171 D.Entries.resize(TruncatedElements);
2181 RL = &Info.Ctx.getASTRecordLayout(Derived);
2184 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
2185 Obj.addDecl(Info, E, Base,
false);
2197 SubobjectDesignator &D = Obj.Designator;
2202 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
2208 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
2210 Obj.addDecl(Info, E, BaseDecl,
true);
2218 PathI != PathE; ++PathI) {
2222 Type = (*PathI)->getType();
2234 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
2238 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
2239 LVal.addDecl(Info, E, FD);
2247 for (
const auto *
C : IFD->
chain())
2259 Size = CharUnits::One();
2275 Size = Info.Ctx.getTypeSizeInChars(Type);
2287 APSInt Adjustment) {
2292 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
2298 int64_t Adjustment) {
2300 APSInt::get(Adjustment));
2315 LVal.Offset += SizeOfComponent;
2317 LVal.addComplex(Info, E, EltTy, Imag);
2334 const VarDecl *VD, CallStackFrame *Frame,
2339 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
2342 if (Info.checkingPotentialConstantExpression())
2344 if (!Frame || !Frame->Arguments) {
2345 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2348 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
2354 Result = Frame->getTemporary(VD);
2362 "missing value for local variable");
2363 if (Info.checkingPotentialConstantExpression())
2367 diag::note_unimplemented_constexpr_lambda_feature_ast)
2368 <<
"captures not currently allowed";
2379 if (!Info.checkingPotentialConstantExpression())
2380 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2386 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
2387 Result = Info.EvaluatingDeclValue;
2394 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2402 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant,
2403 Notes.size() + 1) << VD;
2404 Info.Note(VD->
getLocation(), diag::note_declared_at);
2405 Info.addNotes(Notes);
2408 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2409 Notes.size() + 1) << VD;
2410 Info.Note(VD->
getLocation(), diag::note_declared_at);
2411 Info.addNotes(Notes);
2431 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2435 llvm_unreachable(
"base class missing from derived class's bases list");
2442 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
2444 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
2445 assert(Index <= Str.size() &&
"Index too large");
2446 return APSInt::getUnsigned(Str.c_str()[Index]);
2449 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2450 Lit = PE->getFunctionName();
2453 Info.Ctx.getAsConstantArrayType(S->
getType());
2454 assert(CAT &&
"string literal isn't an array");
2455 QualType CharType = CAT->getElementType();
2456 assert(CharType->
isIntegerType() &&
"unexpected character type");
2460 if (Index < S->getLength())
2470 Info.Ctx.getAsConstantArrayType(S->
getType());
2471 assert(CAT &&
"string literal isn't an array");
2472 QualType CharType = CAT->getElementType();
2473 assert(CharType->
isIntegerType() &&
"unexpected character type");
2475 unsigned Elts = CAT->getSize().getZExtValue();
2491 assert(Index < Size);
2495 unsigned NewElts =
std::max(Index+1, OldElts * 2);
2500 for (
unsigned I = 0; I != OldElts; ++
I)
2502 for (
unsigned I = OldElts; I != NewElts; ++
I)
2506 Array.
swap(NewValue);
2521 for (
auto *Field : RD->
fields())
2525 for (
auto &BaseSpec : RD->
bases())
2543 for (
auto *Field : RD->
fields()) {
2548 if (Field->isMutable() &&
2550 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field;
2551 Info.Note(Field->getLocation(), diag::note_declared_at);
2559 for (
auto &BaseSpec : RD->
bases())
2578 struct CompleteObject {
2584 CompleteObject() :
Value(
nullptr) {}
2586 :
Value(Value), Type(Type) {
2587 assert(Value &&
"missing value for complete object");
2590 explicit operator bool()
const {
return Value; }
2595 template<
typename Sub
objectHandler>
2596 typename SubobjectHandler::result_type
2598 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
2601 return handler.failed();
2602 if (Sub.isOnePastTheEnd()) {
2603 if (Info.getLangOpts().CPlusPlus11)
2604 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2605 << handler.AccessKind;
2608 return handler.failed();
2616 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++
I) {
2618 if (!Info.checkingPotentialConstantExpression())
2619 Info.FFDiag(E, diag::note_constexpr_access_uninit) << handler.AccessKind;
2620 return handler.failed();
2630 return handler.failed();
2632 if (!handler.found(*O, ObjType))
2636 if (handler.AccessKind !=
AK_Read &&
2644 LastField =
nullptr;
2648 assert(CAT &&
"vla in literal type?");
2649 uint64_t Index = Sub.Entries[
I].ArrayIndex;
2650 if (CAT->
getSize().ule(Index)) {
2653 if (Info.getLangOpts().CPlusPlus11)
2654 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2655 << handler.AccessKind;
2658 return handler.failed();
2666 assert(I == N - 1 &&
"extracting subobject of character?");
2668 if (handler.AccessKind !=
AK_Read)
2672 return handler.foundString(*O, ObjType, Index);
2677 else if (handler.AccessKind !=
AK_Read) {
2684 uint64_t Index = Sub.Entries[
I].ArrayIndex;
2686 if (Info.getLangOpts().CPlusPlus11)
2687 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2688 << handler.AccessKind;
2691 return handler.failed();
2696 if (WasConstQualified)
2699 assert(I == N - 1 &&
"extracting subobject of scalar?");
2708 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
2709 if (Field->isMutable() && handler.AccessKind ==
AK_Read) {
2710 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1)
2712 Info.Note(Field->getLocation(), diag::note_declared_at);
2713 return handler.failed();
2722 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
2723 << handler.AccessKind << Field << !UnionField << UnionField;
2724 return handler.failed();
2731 ObjType = Field->getType();
2732 if (WasConstQualified && !Field->isMutable())
2736 if (Info.getLangOpts().CPlusPlus) {
2738 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
2739 << handler.AccessKind << 2 << Field;
2740 Info.Note(Field->getLocation(), diag::note_declared_at);
2742 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2744 return handler.failed();
2755 ObjType = Info.Ctx.getRecordType(Base);
2756 if (WasConstQualified)
2763 struct ExtractSubobjectHandler {
2769 typedef bool result_type;
2770 bool failed() {
return false; }
2775 bool found(APSInt &Value,
QualType SubobjType) {
2779 bool found(APFloat &Value,
QualType SubobjType) {
2783 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2795 const CompleteObject &Obj,
2796 const SubobjectDesignator &Sub,
2798 ExtractSubobjectHandler Handler = { Info, Result };
2803 struct ModifySubobjectHandler {
2808 typedef bool result_type;
2814 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
2820 bool failed() {
return false; }
2822 if (!checkConst(SubobjType))
2825 Subobj.
swap(NewVal);
2828 bool found(APSInt &Value,
QualType SubobjType) {
2829 if (!checkConst(SubobjType))
2831 if (!NewVal.isInt()) {
2836 Value = NewVal.getInt();
2839 bool found(APFloat &Value,
QualType SubobjType) {
2840 if (!checkConst(SubobjType))
2842 Value = NewVal.getFloat();
2845 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2846 llvm_unreachable(
"shouldn't encounter string elements with ExpandArrays");
2855 const CompleteObject &Obj,
2856 const SubobjectDesignator &Sub,
2858 ModifySubobjectHandler Handler = { Info, NewVal, E };
2865 const SubobjectDesignator &A,
2866 const SubobjectDesignator &B,
2867 bool &WasArrayIndex) {
2868 unsigned I = 0, N =
std::min(A.Entries.size(), B.Entries.size());
2869 for (; I != N; ++
I) {
2873 if (A.Entries[I].ArrayIndex != B.Entries[I].ArrayIndex) {
2874 WasArrayIndex =
true;
2882 if (A.Entries[I].BaseOrMember != B.Entries[I].BaseOrMember) {
2883 WasArrayIndex =
false;
2886 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
2888 ObjType = FD->getType();
2894 WasArrayIndex =
false;
2901 const SubobjectDesignator &A,
2902 const SubobjectDesignator &B) {
2903 if (A.Entries.size() != B.Entries.size())
2906 bool IsArray = A.MostDerivedIsArrayElement;
2907 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
2916 return CommonLength >= A.Entries.size() - IsArray;
2924 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
2925 return CompleteObject();
2928 CallStackFrame *Frame =
nullptr;
2929 if (LVal.CallIndex) {
2930 Frame = Info.getCallFrame(LVal.CallIndex);
2932 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
2933 << AK << LVal.Base.is<
const ValueDecl*>();
2935 return CompleteObject();
2944 if (Info.getLangOpts().CPlusPlus)
2945 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
2949 return CompleteObject();
2954 QualType BaseType = getType(LVal.Base);
2971 return CompleteObject();
2976 if (Info.getLangOpts().CPlusPlus) {
2977 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
2979 Info.Note(VD->getLocation(), diag::note_declared_at);
2983 return CompleteObject();
2989 if (Info.getLangOpts().CPlusPlus14 &&
2990 VD == Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()) {
2996 Info.FFDiag(E, diag::note_constexpr_modify_global);
2997 return CompleteObject();
3003 (Info.getLangOpts().OpenCL &&
3005 if (Info.getLangOpts().CPlusPlus) {
3006 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
3007 Info.Note(VD->
getLocation(), diag::note_declared_at);
3011 return CompleteObject();
3017 if (Info.getLangOpts().CPlusPlus11) {
3018 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3019 Info.Note(VD->
getLocation(), diag::note_declared_at);
3024 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD;
3028 if (Info.checkingPotentialConstantExpression() &&
3032 }
else if (Info.getLangOpts().CPlusPlus11) {
3033 Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3034 Info.Note(VD->
getLocation(), diag::note_declared_at);
3038 return CompleteObject();
3043 return CompleteObject();
3045 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3049 dyn_cast<MaterializeTemporaryExpr>(Base)) {
3050 assert(MTE->getStorageDuration() ==
SD_Static &&
3051 "should have a frame for a non-global materialized temporary");
3068 const ValueDecl *ED = MTE->getExtendingDecl();
3071 !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) {
3072 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
3073 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
3074 return CompleteObject();
3077 BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE,
false);
3078 assert(BaseVal &&
"got reference to unevaluated temporary");
3081 return CompleteObject();
3084 BaseVal = Frame->getTemporary(Base);
3085 assert(BaseVal &&
"missing value for temporary");
3090 if (Info.getLangOpts().CPlusPlus) {
3091 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3093 Info.Note(Base->
getExprLoc(), diag::note_constexpr_temporary_here);
3097 return CompleteObject();
3105 if (LVal.getLValueBase() == Info.EvaluatingDecl) {
3115 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
3116 Info.EvalStatus.HasSideEffects) ||
3117 (AK !=
AK_Read && Info.IsSpeculativelyEvaluating))
3118 return CompleteObject();
3120 return CompleteObject(BaseVal, BaseType);
3136 const LValue &LVal,
APValue &RVal) {
3137 if (LVal.Designator.Invalid)
3141 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3152 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
3154 CompleteObject LitObj(&Lit, Base->
getType());
3156 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
3161 CompleteObject StrObj(&Str, Base->
getType());
3173 if (LVal.Designator.Invalid)
3176 if (!Info.getLangOpts().CPlusPlus14) {
3191 struct CompoundAssignSubobjectHandler {
3200 typedef bool result_type;
3205 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3211 bool failed() {
return false; }
3215 return found(Subobj.
getInt(), SubobjType);
3216 case APValue::Float:
3217 return found(Subobj.
getFloat(), SubobjType);
3218 case APValue::ComplexInt:
3219 case APValue::ComplexFloat:
3223 case APValue::LValue:
3224 return foundPointer(Subobj, SubobjType);
3231 bool found(APSInt &Value,
QualType SubobjType) {
3232 if (!checkConst(SubobjType))
3249 bool found(APFloat &Value,
QualType SubobjType) {
3250 return checkConst(SubobjType) &&
3257 if (!checkConst(SubobjType))
3264 if (PointeeType.
isNull() || !RHS.isInt() ||
3265 (Opcode != BO_Add && Opcode != BO_Sub)) {
3270 APSInt
Offset = RHS.getInt();
3271 if (Opcode == BO_Sub)
3275 LVal.setFrom(Info.Ctx, Subobj);
3278 LVal.moveInto(Subobj);
3281 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3282 llvm_unreachable(
"shouldn't encounter string elements here");
3291 EvalInfo &Info,
const Expr *E,
3294 if (LVal.Designator.Invalid)
3297 if (!Info.getLangOpts().CPlusPlus14) {
3303 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
3305 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3309 struct IncDecSubobjectHandler {
3315 typedef bool result_type;
3320 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3326 bool failed() {
return false; }
3337 return found(Subobj.
getInt(), SubobjType);
3338 case APValue::Float:
3339 return found(Subobj.
getFloat(), SubobjType);
3340 case APValue::ComplexInt:
3344 case APValue::ComplexFloat:
3348 case APValue::LValue:
3349 return foundPointer(Subobj, SubobjType);
3356 bool found(APSInt &Value,
QualType SubobjType) {
3357 if (!checkConst(SubobjType))
3367 if (Old) *Old =
APValue(Value);
3379 bool WasNegative = Value.isNegative();
3383 if (!WasNegative && Value.isNegative() &&
3385 APSInt ActualValue(Value,
true);
3391 if (WasNegative && !Value.isNegative() &&
3393 unsigned BitWidth = Value.getBitWidth();
3394 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
3395 ActualValue.setBit(BitWidth);
3401 bool found(APFloat &Value,
QualType SubobjType) {
3402 if (!checkConst(SubobjType))
3405 if (Old) *Old =
APValue(Value);
3407 APFloat One(Value.getSemantics(), 1);
3409 Value.add(One, APFloat::rmNearestTiesToEven);
3411 Value.subtract(One, APFloat::rmNearestTiesToEven);
3415 if (!checkConst(SubobjType))
3427 LVal.setFrom(Info.Ctx, Subobj);
3431 LVal.moveInto(Subobj);
3434 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3435 llvm_unreachable(
"shouldn't encounter string elements here");
3443 if (LVal.Designator.Invalid)
3446 if (!Info.getLangOpts().CPlusPlus14) {
3453 IncDecSubobjectHandler Handler = { Info,
E, AK, Old };
3454 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3469 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
3488 bool IncludeMember =
true) {
3495 if (!MemPtr.getDecl()) {
3501 if (MemPtr.isDerivedMember()) {
3505 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
3506 LV.Designator.Entries.size()) {
3510 unsigned PathLengthToMember =
3511 LV.Designator.Entries.size() - MemPtr.Path.size();
3512 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++
I) {
3514 LV.Designator.Entries[PathLengthToMember + I]);
3524 PathLengthToMember))
3526 }
else if (!MemPtr.Path.empty()) {
3528 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
3529 MemPtr.Path.size() + IncludeMember);
3535 assert(RD &&
"member pointer access on non-class-type expression");
3537 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++
I) {
3545 MemPtr.getContainingRecord()))
3550 if (IncludeMember) {
3551 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
3555 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
3559 llvm_unreachable(
"can't construct reference to bound member function");
3563 return MemPtr.getDecl();
3569 bool IncludeMember =
true) {
3573 if (Info.noteFailure()) {
3581 BO->
getRHS(), IncludeMember);
3588 SubobjectDesignator &D = Result.Designator;
3589 if (D.Invalid || !Result.checkNullPointer(Info, E, CSK_Derived))
3597 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
3598 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3599 << D.MostDerivedType << TargetQT;
3605 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
3608 if (NewEntriesSize == D.MostDerivedPathLength)
3609 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
3611 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
3613 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3614 << D.MostDerivedType << TargetQT;
3645 Result.set(VD, Info.CurrentCall->Index);
3646 APValue &Val = Info.CurrentCall->createTemporary(VD,
true);
3650 Info.FFDiag(VD->
getLocStart(), diag::note_constexpr_uninitialized)
3672 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
3676 for (
auto *BD : DD->bindings())
3677 if (
auto *VD = BD->getHoldingVar())
3686 const Expr *Cond,
bool &Result) {
3687 FullExpressionRAII
Scope(Info);
3712 BlockScopeRAII
Scope(Info);
3715 return ESR_Succeeded;
3718 return ESR_Continue;
3721 case ESR_CaseNotFound:
3724 llvm_unreachable(
"Invalid EvalStmtResult!");
3730 BlockScopeRAII
Scope(Info);
3735 FullExpressionRAII Scope(Info);
3738 if (ESR != ESR_Succeeded)
3753 if (isa<DefaultStmt>(SC)) {
3758 const CaseStmt *CS = cast<CaseStmt>(SC);
3762 if (LHS <= Value && Value <= RHS) {
3769 return ESR_Succeeded;
3774 return ESR_Succeeded;
3780 case ESR_CaseNotFound:
3783 Info.FFDiag(Found->
getLocStart(), diag::note_constexpr_stmt_expr_unsupported);
3786 llvm_unreachable(
"Invalid EvalStmtResult!");
3792 if (!Info.nextStep(S))
3803 case Stmt::CompoundStmtClass:
3807 case Stmt::LabelStmtClass:
3808 case Stmt::AttributedStmtClass:
3809 case Stmt::DoStmtClass:
3812 case Stmt::CaseStmtClass:
3813 case Stmt::DefaultStmtClass:
3818 case Stmt::IfStmtClass: {
3821 const IfStmt *IS = cast<IfStmt>(
S);
3825 BlockScopeRAII
Scope(Info);
3828 if (ESR != ESR_CaseNotFound || !IS->
getElse())
3833 case Stmt::WhileStmtClass: {
3836 if (ESR != ESR_Continue)
3841 case Stmt::ForStmtClass: {
3842 const ForStmt *FS = cast<ForStmt>(
S);
3845 if (ESR != ESR_Continue)
3848 FullExpressionRAII IncScope(Info);
3855 case Stmt::DeclStmtClass:
3859 return ESR_CaseNotFound;
3865 if (
const Expr *E = dyn_cast<Expr>(S)) {
3868 FullExpressionRAII
Scope(Info);
3871 return ESR_Succeeded;
3877 case Stmt::NullStmtClass:
3878 return ESR_Succeeded;
3880 case Stmt::DeclStmtClass: {
3882 for (
const auto *DclIt : DS->
decls()) {
3886 FullExpressionRAII
Scope(Info);
3890 return ESR_Succeeded;
3893 case Stmt::ReturnStmtClass: {
3894 const Expr *RetExpr = cast<ReturnStmt>(
S)->getRetValue();
3895 FullExpressionRAII
Scope(Info);
3899 :
Evaluate(Result.Value, Info, RetExpr)))
3901 return ESR_Returned;
3904 case Stmt::CompoundStmtClass: {
3905 BlockScopeRAII
Scope(Info);
3908 for (
const auto *BI : CS->
body()) {
3910 if (ESR == ESR_Succeeded)
3912 else if (ESR != ESR_CaseNotFound)
3915 return Case ? ESR_CaseNotFound : ESR_Succeeded;
3918 case Stmt::IfStmtClass: {
3919 const IfStmt *IS = cast<IfStmt>(
S);
3922 BlockScopeRAII
Scope(Info);
3925 if (ESR != ESR_Succeeded)
3934 if (ESR != ESR_Succeeded)
3937 return ESR_Succeeded;
3940 case Stmt::WhileStmtClass: {
3943 BlockScopeRAII
Scope(Info);
3952 if (ESR != ESR_Continue)
3955 return ESR_Succeeded;
3958 case Stmt::DoStmtClass: {
3959 const DoStmt *DS = cast<DoStmt>(
S);
3963 if (ESR != ESR_Continue)
3967 FullExpressionRAII CondScope(Info);
3971 return ESR_Succeeded;
3974 case Stmt::ForStmtClass: {
3975 const ForStmt *FS = cast<ForStmt>(
S);
3976 BlockScopeRAII
Scope(Info);
3979 if (ESR != ESR_Succeeded)
3983 BlockScopeRAII Scope(Info);
3984 bool Continue =
true;
3992 if (ESR != ESR_Continue)
3996 FullExpressionRAII IncScope(Info);
4001 return ESR_Succeeded;
4004 case Stmt::CXXForRangeStmtClass: {
4006 BlockScopeRAII
Scope(Info);
4010 if (ESR != ESR_Succeeded)
4015 if (ESR != ESR_Succeeded)
4018 if (ESR != ESR_Succeeded)
4024 bool Continue =
true;
4025 FullExpressionRAII CondExpr(Info);
4033 BlockScopeRAII InnerScope(Info);
4035 if (ESR != ESR_Succeeded)
4040 if (ESR != ESR_Continue)
4048 return ESR_Succeeded;
4051 case Stmt::SwitchStmtClass:
4054 case Stmt::ContinueStmtClass:
4055 return ESR_Continue;
4057 case Stmt::BreakStmtClass:
4060 case Stmt::LabelStmtClass:
4061 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
4063 case Stmt::AttributedStmtClass:
4066 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
4069 case Stmt::CaseStmtClass:
4070 case Stmt::DefaultStmtClass:
4071 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
4081 bool IsValueInitialization) {
4088 if (!CD->
isConstexpr() && !IsValueInitialization) {
4089 if (Info.getLangOpts().CPlusPlus11) {
4092 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
4094 Info.Note(CD->
getLocation(), diag::note_declared_at);
4096 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
4110 if (Info.checkingPotentialConstantExpression() && !Definition &&
4124 if (Info.getLangOpts().CPlusPlus11) {
4125 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
4130 if (CD && CD->isInheritingConstructor()) {
4132 if (!Inherited->isConstexpr())
4133 DiagDecl = CD = Inherited;
4139 if (CD && CD->isInheritingConstructor())
4140 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
4141 << CD->getInheritedConstructor().getConstructor()->
getParent();
4143 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
4145 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
4147 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4157 for (
auto *FD : RD->
fields()) {
4158 if (FD->isUnnamedBitfield())
4162 for (
auto &Base : RD->
bases())
4163 if (
hasFields(Base.getType()->getAsCXXRecordDecl()))
4175 bool Success =
true;
4178 if (!
Evaluate(ArgValues[I - Args.begin()], Info, *
I)) {
4181 if (!Info.noteFailure())
4193 EvalInfo &Info,
APValue &Result,
4194 const LValue *ResultSlot) {
4195 ArgVector ArgValues(Args.size());
4199 if (!Info.CheckCallLimit(CallLoc))
4202 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
4211 if (MD && MD->isDefaulted() &&
4212 (MD->getParent()->isUnion() ||
4213 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
4215 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
4217 RHS.setFrom(Info.Ctx, ArgValues[0]);
4225 This->moveInto(Result);
4229 MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
4230 Frame.LambdaThisCaptureField);
4235 if (ESR == ESR_Succeeded) {
4238 Info.FFDiag(Callee->
getLocEnd(), diag::note_constexpr_no_return);
4240 return ESR == ESR_Returned;
4247 EvalInfo &Info,
APValue &Result) {
4249 if (!Info.CheckCallLimit(CallLoc))
4254 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
4258 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
4269 FullExpressionRAII InitScope(Info);
4288 RHS.setFrom(Info.Ctx, ArgValues[0]);
4303 BlockScopeRAII LifetimeExtendedScope(Info);
4305 bool Success =
true;
4306 unsigned BasesSeen = 0;
4310 for (
const auto *I : Definition->
inits()) {
4311 LValue Subobject = This;
4316 if (I->isBaseInitializer()) {
4317 QualType BaseType(I->getBaseClass(), 0);
4321 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
4322 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
4323 "base class initializers not in expected order");
4327 BaseType->getAsCXXRecordDecl(), &Layout))
4330 }
else if ((FD = I->getMember())) {
4342 for (
auto *
C : IFD->chain()) {
4343 FD = cast<FieldDecl>(
C);
4366 llvm_unreachable(
"unknown base initializer kind");
4369 FullExpressionRAII InitScope(Info);
4375 if (!Info.noteFailure())
4388 EvalInfo &Info,
APValue &Result) {
4389 ArgVector ArgValues(Args.size());
4402 template <
class Derived>
4403 class ExprEvaluatorBase
4406 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
4407 bool DerivedSuccess(
const APValue &V,
const Expr *E) {
4408 return getDerived().Success(V, E);
4410 bool DerivedZeroInitialization(
const Expr *E) {
4411 return getDerived().ZeroInitialization(E);
4417 template<
typename ConditionalOperator>
4419 assert(Info.checkingPotentialConstantExpression());
4424 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4431 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4438 Error(E, diag::note_constexpr_conditional_never_const);
4442 template<
typename ConditionalOperator>
4446 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
4447 CheckPotentialConstantConditional(E);
4450 if (Info.noteFailure()) {
4458 return StmtVisitorTy::Visit(EvalExpr);
4464 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
4467 return Info.CCEDiag(E, D);
4470 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
4473 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
4475 EvalInfo &getEvalInfo() {
return Info; }
4484 return Error(E, diag::note_invalid_subexpr_in_const_expr);
4487 bool VisitStmt(
const Stmt *) {
4488 llvm_unreachable(
"Expression evaluator should not be called on stmts");
4490 bool VisitExpr(
const Expr *E) {
4495 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4497 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4499 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4507 {
return StmtVisitorTy::Visit(E->
getExpr()); }
4512 return StmtVisitorTy::Visit(E->
getExpr());
4517 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4520 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
4521 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4524 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
4525 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4534 VisitIgnoredValue(E->
getLHS());
4535 return StmtVisitorTy::Visit(E->
getRHS());
4545 return DerivedSuccess(Result, E);
4557 return HandleConditionalOperator(E);
4561 bool IsBcpCall =
false;
4568 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
4573 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
4576 FoldConstant Fold(Info, IsBcpCall);
4577 if (!HandleConditionalOperator(E)) {
4578 Fold.keepDiagnostics();
4586 if (
APValue *Value = Info.CurrentCall->getTemporary(E))
4587 return DerivedSuccess(*Value, E);
4593 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
4596 return StmtVisitorTy::Visit(Source);
4599 bool VisitCallExpr(
const CallExpr *E) {
4601 if (!handleCallExpr(E, Result,
nullptr))
4603 return DerivedSuccess(Result, E);
4607 const LValue *ResultSlot) {
4612 LValue *This =
nullptr, ThisVal;
4614 bool HasQualifier =
false;
4619 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
4623 Member = ME->getMemberDecl();
4625 HasQualifier = ME->hasQualifier();
4626 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
4629 if (!Member)
return false;
4632 return Error(Callee);
4636 return Error(Callee);
4642 if (!Call.getLValueOffset().isZero())
4643 return Error(Callee);
4644 FD = dyn_cast_or_null<FunctionDecl>(
4645 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
4647 return Error(Callee);
4650 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
4668 Args = Args.slice(1);
4677 "Number of captures must be zero for conversion to function-ptr");
4688 "A generic lambda's static-invoker function must be a "
4689 "template specialization");
4692 LambdaCallOp->getDescribedFunctionTemplate();
4693 void *InsertPos =
nullptr;
4696 assert(CorrespondingCallOpSpecialization &&
4697 "We must always have a function call operator specialization "
4698 "that corresponds to our static invoker specialization");
4699 FD = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
4708 if (This && !This->checkSubobject(Info, E, CSK_This))
4713 if (This && !HasQualifier &&
4714 isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
4715 return Error(E, diag::note_constexpr_virtual_call);
4733 return DerivedZeroInitialization(E);
4735 return StmtVisitorTy::Visit(E->
getInit(0));
4739 return DerivedZeroInitialization(E);
4742 return DerivedZeroInitialization(E);
4745 return DerivedZeroInitialization(E);
4750 assert(!E->
isArrow() &&
"missing call to bound member function?");
4759 if (!FD)
return Error(E);
4764 CompleteObject Obj(&Val, BaseTy);
4770 DerivedSuccess(Result, E);
4773 bool VisitCastExpr(
const CastExpr *E) {
4778 case CK_AtomicToNonAtomic: {
4785 return DerivedSuccess(AtomicVal, E);
4789 case CK_UserDefinedConversion:
4790 return StmtVisitorTy::Visit(E->
getSubExpr());
4792 case CK_LValueToRValue: {
4801 return DerivedSuccess(RVal, E);
4809 return VisitUnaryPostIncDec(UO);
4812 return VisitUnaryPostIncDec(UO);
4815 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4825 return DerivedSuccess(RVal, UO);
4828 bool VisitStmtExpr(
const StmtExpr *E) {
4831 if (Info.checkingForOverflow())
4834 BlockScopeRAII
Scope(Info);
4843 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
4845 Info.FFDiag((*BI)->getLocStart(),
4846 diag::note_constexpr_stmt_expr_unsupported);
4849 return this->
Visit(FinalExpr);
4853 StmtResult Result = { ReturnValue,
nullptr };
4855 if (ESR != ESR_Succeeded) {
4859 if (ESR != ESR_Failed)
4860 Info.FFDiag((*BI)->getLocStart(),
4861 diag::note_constexpr_stmt_expr_unsupported);
4866 llvm_unreachable(
"Return from function from the loop above.");
4870 void VisitIgnoredValue(
const Expr *E) {
4875 void VisitIgnoredBaseExpression(
const Expr *E) {
4878 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
4880 VisitIgnoredValue(E);
4890 template<
class Derived>
4891 class LValueExprEvaluatorBase
4892 :
public ExprEvaluatorBase<Derived> {
4896 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
4897 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
4904 bool evaluatePointer(
const Expr *E, LValue &Result) {
4909 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
4910 : ExprEvaluatorBaseTy(Info), Result(Result),
4911 InvalidBaseOK(InvalidBaseOK) {}
4914 Result.setFrom(this->Info.Ctx, V);
4930 EvalOK = this->Visit(E->
getBase());
4936 Result.setInvalid(E);
4951 return this->
Error(E);
4966 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
4974 bool VisitCastExpr(
const CastExpr *E) {
4977 return ExprEvaluatorBaseTy::VisitCastExpr(E);
4979 case CK_DerivedToBase:
4980 case CK_UncheckedDerivedToBase:
5025 class LValueExprEvaluator
5026 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
5028 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
5029 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
5031 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
5048 return VisitUnaryPreIncDec(UO);
5051 return VisitUnaryPreIncDec(UO);
5056 bool VisitCastExpr(
const CastExpr *E) {
5059 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
5061 case CK_LValueBitCast:
5062 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5065 Result.Designator.setInvalid();
5068 case CK_BaseToDerived:
5083 bool InvalidBaseOK) {
5086 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
5089 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
5093 return VisitVarDecl(E, VD);
5095 return Visit(BD->getBinding());
5100 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
5107 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
5108 if (Info.checkingPotentialConstantExpression())
5111 Result = *Info.CurrentCall->This;
5123 Result.setFrom(Info.Ctx, RVal);
5128 CallStackFrame *Frame =
nullptr;
5136 if (Info.CurrentCall->Callee &&
5138 Frame = Info.CurrentCall;
5144 Result.set(VD, Frame->Index);
5154 if (!Info.checkingPotentialConstantExpression())
5155 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
5161 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
5167 skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
5170 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++
I)
5179 Value = Info.Ctx.getMaterializedTemporaryValue(E,
true);
5183 Value = &Info.CurrentCall->
5185 Result.set(E, Info.CurrentCall->Index);
5199 for (
unsigned I = Adjustments.size(); I != 0; ) {
5201 switch (Adjustments[I].
Kind) {
5202 case SubobjectAdjustment::DerivedToBaseAdjustment:
5206 Type = Adjustments[
I].DerivedToBase.BasePath->getType();
5209 case SubobjectAdjustment::FieldAdjustment:
5212 Type = Adjustments[
I].Field->getType();
5215 case SubobjectAdjustment::MemberPointerAdjustment:
5217 Adjustments[I].Ptr.RHS))
5219 Type = Adjustments[
I].Ptr.MPT->getPointeeType();
5229 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
5230 "lvalue compound literal in c++?");
5236 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
5240 Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
5246 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
5250 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
5253 VisitIgnoredBaseExpression(E->
getBase());
5254 return VisitVarDecl(E, VD);
5259 if (MD->isStatic()) {
5260 VisitIgnoredBaseExpression(E->
getBase());
5266 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
5276 if (!Info.noteFailure())
5289 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
5293 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
5302 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
5304 "lvalue __imag__ on scalar?");
5311 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
5312 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5323 bool LValueExprEvaluator::VisitCompoundAssignOperator(
5325 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5331 if (!this->Visit(CAO->
getLHS())) {
5332 if (Info.noteFailure())
5346 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
5347 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5352 if (!this->Visit(E->
getLHS())) {
5353 if (Info.noteFailure())
5377 llvm::APInt &Result) {
5378 const AllocSizeAttr *AllocSize = getAllocSizeAttr(Call);
5381 assert(AllocSize && AllocSize->getElemSizeParam() != 0);
5382 unsigned SizeArgNo = AllocSize->getElemSizeParam() - 1;
5387 auto EvaluateAsSizeT = [&](
const Expr *
E, APSInt &Into) {
5388 if (!E->
EvaluateAsInt(Into, Ctx, Expr::SE_AllowSideEffects))
5390 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
5392 Into = Into.zextOrSelf(BitsInSizeT);
5397 if (!EvaluateAsSizeT(Call->
getArg(SizeArgNo), SizeOfElem))
5400 if (!AllocSize->getNumElemsParam()) {
5401 Result = std::move(SizeOfElem);
5405 APSInt NumberOfElems;
5407 unsigned NumArgNo = AllocSize->getNumElemsParam() - 1;
5408 if (!EvaluateAsSizeT(Call->
getArg(NumArgNo), NumberOfElems))
5412 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
5416 Result = std::move(BytesAvailable);
5424 llvm::APInt &Result) {
5425 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
5426 "Can't get the size of a non alloc_size function");
5427 const auto *Base = LVal.getLValueBase().get<
const Expr *>();
5428 const CallExpr *CE = tryUnwrapAllocSizeCall(Base);
5447 dyn_cast_or_null<VarDecl>(Base.dyn_cast<
const ValueDecl *>());
5456 if (!tryUnwrapAllocSizeCall(E))
5461 Result.setInvalid(E);
5464 Result.addUnsizedArray(Info, Pointee);
5469 class PointerExprEvaluator
5470 :
public ExprEvaluatorBase<PointerExprEvaluator> {
5474 bool Success(
const Expr *E) {
5479 bool evaluateLValue(
const Expr *E, LValue &Result) {
5483 bool evaluatePointer(
const Expr *E, LValue &Result) {
5487 bool visitNonBuiltinCallExpr(
const CallExpr *E);
5490 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
5491 : ExprEvaluatorBaseTy(info), Result(Result),
5492 InvalidBaseOK(InvalidBaseOK) {}
5495 Result.setFrom(Info.Ctx, V);
5498 bool ZeroInitialization(
const Expr *E) {
5499 auto TargetVal = Info.Ctx.getTargetNullPointerValue(E->
getType());
5500 Result.setNull(E->
getType(), TargetVal);
5505 bool VisitCastExpr(
const CastExpr* E);
5508 {
return Success(E); }
5510 if (Info.noteFailure())
5515 {
return Success(E); }
5516 bool VisitCallExpr(
const CallExpr *E);
5517 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
5518 bool VisitBlockExpr(
const BlockExpr *E) {
5525 if (Info.checkingPotentialConstantExpression())
5527 if (!Info.CurrentCall->This) {
5528 if (Info.getLangOpts().CPlusPlus11)
5529 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
5534 Result = *Info.CurrentCall->This;
5543 Info.CurrentCall->LambdaThisCaptureField))
5546 if (Info.CurrentCall->LambdaThisCaptureField->getType()
5547 ->isPointerType()) {
5553 Result.setFrom(Info.Ctx, RVal);
5564 bool InvalidBaseOK) {
5566 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
5569 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
5572 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
5577 std::swap(PExp, IExp);
5579 bool EvalPtrOK = evaluatePointer(PExp, Result);
5580 if (!EvalPtrOK && !Info.noteFailure())
5594 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
5598 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr* E) {
5606 case CK_CPointerToObjCPointerCast:
5607 case CK_BlockPointerToObjCPointerCast:
5608 case CK_AnyPointerToBlockPointerCast:
5609 case CK_AddressSpaceConversion:
5610 if (!Visit(SubExpr))
5616 Result.Designator.setInvalid();
5618 CCEDiag(E, diag::note_constexpr_invalid_cast)
5621 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5623 if (E->
getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
5624 ZeroInitialization(E);
5627 case CK_DerivedToBase:
5628 case CK_UncheckedDerivedToBase:
5631 if (!Result.Base && Result.Offset.isZero())
5637 castAs<PointerType>()->getPointeeType(),
5640 case CK_BaseToDerived:
5643 if (!Result.Base && Result.Offset.isZero())
5647 case CK_NullToPointer:
5649 return ZeroInitialization(E);
5651 case CK_IntegralToPointer: {
5652 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5658 if (Value.
isInt()) {
5659 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
5660 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
5661 Result.Base = (
Expr*)
nullptr;
5662 Result.InvalidBase =
false;
5663 Result.Offset = CharUnits::fromQuantity(N);
5664 Result.CallIndex = 0;
5665 Result.Designator.setInvalid();
5666 Result.IsNullPtr =
false;
5670 Result.setFrom(Info.Ctx, Value);
5674 case CK_ArrayToPointerDecay:
5676 if (!evaluateLValue(SubExpr, Result))
5679 Result.set(SubExpr, Info.CurrentCall->Index);
5680 if (!
EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr,
false),
5686 = Info.Ctx.getAsConstantArrayType(SubExpr->
getType()))
5687 Result.addArray(Info, E, CAT);
5689 Result.Designator.setInvalid();
5692 case CK_FunctionToPointerDecay:
5693 return evaluateLValue(SubExpr, Result);
5695 case CK_LValueToRValue: {
5704 return InvalidBaseOK &&
5706 return Success(RVal, E);
5710 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5722 return CharUnits::One();
5723 return Info.Ctx.toCharUnitsFromBits(
5724 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
5736 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
5737 return Info.Ctx.getDeclAlign(DRE->getDecl(),
5740 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
5741 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
5748 bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
5749 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
5752 if (!(InvalidBaseOK && getAllocSizeAttr(E)))
5755 Result.setInvalid(E);
5757 Result.addUnsizedArray(Info, PointeeTy);
5761 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
5766 return VisitBuiltinCallExpr(E, BuiltinOp);
5768 return visitNonBuiltinCallExpr(E);
5771 bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
5772 unsigned BuiltinOp) {
5773 switch (BuiltinOp) {
5774 case Builtin::BI__builtin_addressof:
5776 case Builtin::BI__builtin_assume_aligned: {
5783 LValue OffsetResult(Result);
5787 CharUnits Align = CharUnits::fromQuantity(Alignment.getZExtValue());
5794 int64_t AdditionalOffset = -Offset.getZExtValue();
5795 OffsetResult.Offset += CharUnits::fromQuantity(AdditionalOffset);
5799 if (OffsetResult.Base) {
5802 OffsetResult.Base.dyn_cast<
const ValueDecl*>()) {
5803 BaseAlignment = Info.Ctx.getDeclAlign(VD);
5809 if (BaseAlignment < Align) {
5810 Result.Designator.setInvalid();
5813 diag::note_constexpr_baa_insufficient_alignment) << 0
5814 << (
unsigned)BaseAlignment.getQuantity()
5815 << (
unsigned)Align.getQuantity();
5821 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
5822 Result.Designator.setInvalid();
5826 diag::note_constexpr_baa_insufficient_alignment) << 1
5828 diag::note_constexpr_baa_value_insufficient_alignment))
5829 << (int)OffsetResult.Offset.getQuantity()
5837 case Builtin::BIstrchr:
5838 case Builtin::BIwcschr:
5839 case Builtin::BImemchr:
5840 case Builtin::BIwmemchr:
5841 if (Info.getLangOpts().CPlusPlus11)
5842 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
5844 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
5846 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
5848 case Builtin::BI__builtin_strchr:
5849 case Builtin::BI__builtin_wcschr:
5850 case Builtin::BI__builtin_memchr:
5851 case Builtin::BI__builtin_char_memchr:
5852 case Builtin::BI__builtin_wmemchr: {
5853 if (!Visit(E->
getArg(0)))
5858 uint64_t MaxLength = uint64_t(-1);
5859 if (BuiltinOp != Builtin::BIstrchr &&
5860 BuiltinOp != Builtin::BIwcschr &&
5861 BuiltinOp != Builtin::BI__builtin_strchr &&
5862 BuiltinOp != Builtin::BI__builtin_wcschr) {
5866 MaxLength = N.getExtValue();
5873 uint64_t DesiredVal;
5874 bool StopAtNull =
false;
5875 switch (BuiltinOp) {
5876 case Builtin::BIstrchr:
5877 case Builtin::BI__builtin_strchr:
5884 return ZeroInitialization(E);
5887 case Builtin::BImemchr:
5888 case Builtin::BI__builtin_memchr:
5889 case Builtin::BI__builtin_char_memchr:
5893 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
5896 case Builtin::BIwcschr:
5897 case Builtin::BI__builtin_wcschr:
5900 case Builtin::BIwmemchr:
5901 case Builtin::BI__builtin_wmemchr:
5903 DesiredVal = Desired.getZExtValue();
5907 for (; MaxLength; --MaxLength) {
5912 if (Char.
getInt().getZExtValue() == DesiredVal)
5914 if (StopAtNull && !Char.
getInt())
5920 return ZeroInitialization(E);
5924 return visitNonBuiltinCallExpr(E);
5933 class MemberPointerExprEvaluator
5934 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
5938 Result = MemberPtr(D);
5943 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
5944 : ExprEvaluatorBaseTy(Info), Result(Result) {}
5950 bool ZeroInitialization(
const Expr *E) {
5951 return Success((
const ValueDecl*)
nullptr);
5954 bool VisitCastExpr(
const CastExpr *E);
5962 return MemberPointerExprEvaluator(Info, Result).Visit(E);
5965 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5968 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5970 case CK_NullToMemberPointer:
5972 return ZeroInitialization(E);
5974 case CK_BaseToDerivedMemberPointer: {
5982 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
5984 PathI != PathE; ++PathI) {
5985 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
5986 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
5987 if (!Result.castToDerived(Derived))
5996 case CK_DerivedToBaseMemberPointer:
6000 PathE = E->
path_end(); PathI != PathE; ++PathI) {
6001 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
6002 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
6003 if (!Result.castToBase(Base))
6010 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
6013 return Success(cast<DeclRefExpr>(E->
getSubExpr())->getDecl());
6021 class RecordExprEvaluator
6022 :
public ExprEvaluatorBase<RecordExprEvaluator> {
6027 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
6028 : ExprEvaluatorBaseTy(info), This(This), Result(Result) {}
6034 bool ZeroInitialization(
const Expr *E) {
6035 return ZeroInitialization(E, E->
getType());
6039 bool VisitCallExpr(
const CallExpr *E) {
6040 return handleCallExpr(E, Result, &This);
6042 bool VisitCastExpr(
const CastExpr *E);
6045 return VisitCXXConstructExpr(E, E->
getType());
6063 const LValue &This,
APValue &Result) {
6064 assert(!RD->
isUnion() &&
"Expected non-union class type");
6075 End = CD->bases_end(); I !=
End; ++
I, ++Index) {
6076 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
6077 LValue Subobject = This;
6081 Result.getStructBase(Index)))
6086 for (
const auto *I : RD->
fields()) {
6088 if (I->getType()->isReferenceType())
6091 LValue Subobject = This;
6097 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
6104 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
6116 LValue Subobject = This;
6121 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
6124 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
6125 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
6132 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6135 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6137 case CK_ConstructorConversion:
6140 case CK_DerivedToBase:
6141 case CK_UncheckedDerivedToBase: {
6149 APValue *Value = &DerivedObject;
6152 PathE = E->
path_end(); PathI != PathE; ++PathI) {
6153 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
6154 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
6164 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6186 LValue Subobject = This;
6191 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
6192 isa<CXXDefaultInitExpr>(InitExpr));
6194 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
6198 if (Result.isUninit())
6201 unsigned ElementNo = 0;
6202 bool Success =
true;
6206 for (
const auto &Base : CXXRD->bases()) {
6207 assert(ElementNo < E->getNumInits() &&
"missing init for base class");
6210 LValue Subobject = This;
6214 APValue &FieldVal = Result.getStructBase(ElementNo);
6216 if (!Info.noteFailure())
6225 for (
const auto *Field : RD->
fields()) {
6231 LValue Subobject = This;
6238 Subobject, Field, &Layout))
6244 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
6247 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
6248 isa<CXXDefaultInitExpr>(Init));
6250 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
6253 FieldVal, Field))) {
6254 if (!Info.noteFailure())
6273 if (!Result.isUninit())
6284 return ZeroInitialization(E, T);
6288 auto Body = FD->
getBody(Definition);
6296 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
6297 return Visit(ME->GetTemporaryExpr());
6299 if (ZeroInit && !ZeroInitialization(E, T))
6304 cast<CXXConstructorDecl>(Definition), Info,
6308 bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
6310 if (!Info.CurrentCall) {
6311 assert(Info.checkingPotentialConstantExpression());
6320 auto Body = FD->
getBody(Definition);
6326 cast<CXXConstructorDecl>(Definition), Info,
6330 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
6340 Array.addArray(Info, E, ArrayType);
6349 if (!Field->getType()->isPointerType() ||
6350 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
6356 Array.moveInto(Result.getStructField(0));
6361 if (Field->getType()->isPointerType() &&
6362 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
6367 ArrayType->
getSize().getZExtValue()))
6369 Array.moveInto(Result.getStructField(1));
6370 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
6372 Result.getStructField(1) =
APValue(APSInt(ArrayType->
getSize()));
6382 bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
6386 if (Info.checkingPotentialConstantExpression())
return true;
6388 const size_t NumFields =
6393 "The number of lambda capture initializers should equal the number of "
6394 "fields within the closure type");
6401 bool Success =
true;
6402 for (
const auto *Field : ClosureClass->
fields()) {
6405 Expr *
const CurFieldInit = *CaptureInitIt++;
6412 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
6414 if (!Info.keepEvaluatingAfterFailure())
6424 APValue &Result, EvalInfo &Info) {
6426 "can't evaluate expression as a record rvalue");
6427 return RecordExprEvaluator(Info, This, Result).Visit(E);
6438 class TemporaryExprEvaluator
6439 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
6441 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
6442 LValueExprEvaluatorBaseTy(Info, Result, false) {}
6445 bool VisitConstructExpr(
const Expr *E) {
6446 Result.set(E, Info.CurrentCall->Index);
6451 bool VisitCastExpr(
const CastExpr *E) {
6454 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
6456 case CK_ConstructorConversion:
6461 return VisitConstructExpr(E);
6464 return VisitConstructExpr(E);
6466 bool VisitCallExpr(
const CallExpr *E) {
6467 return VisitConstructExpr(E);
6470 return VisitConstructExpr(E);
6473 return VisitConstructExpr(E);
6481 return TemporaryExprEvaluator(Info, Result).Visit(E);
6489 class VectorExprEvaluator
6490 :
public ExprEvaluatorBase<VectorExprEvaluator> {
6494 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
6495 : ExprEvaluatorBaseTy(info), Result(Result) {}
6500 Result =
APValue(V.data(), V.size());
6508 bool ZeroInitialization(
const Expr *E);
6512 bool VisitCastExpr(
const CastExpr* E);
6523 return VectorExprEvaluator(Info, Result).Visit(E);
6526 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6534 case CK_VectorSplat: {
6540 Val =
APValue(std::move(IntResult));
6542 APFloat FloatResult(0.0);
6545 Val =
APValue(std::move(FloatResult));
6552 return Success(Elts, E);
6556 llvm::APInt SValInt;
6561 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
6562 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
6565 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
6566 unsigned FloatEltSize = EltSize;
6567 if (&Sem == &APFloat::x87DoubleExtended())
6569 for (
unsigned i = 0; i < NElts; i++) {
6572 Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
6574 Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
6575 Elts.push_back(
APValue(APFloat(Sem, Elt)));
6578 for (
unsigned i = 0; i < NElts; i++) {
6581 Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
6583 Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
6589 return Success(Elts, E);
6592 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6597 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6609 unsigned CountInits = 0, CountElts = 0;
6610 while (CountElts < NumElements) {
6612 if (CountInits < NumInits
6618 for (
unsigned j = 0; j < vlen; j++)
6622 llvm::APSInt sInt(32);
6623 if (CountInits < NumInits) {
6627 sInt = Info.Ctx.MakeIntValue(0, EltTy);
6628 Elements.push_back(
APValue(sInt));
6631 llvm::APFloat f(0.0);
6632 if (CountInits < NumInits) {
6636 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
6637 Elements.push_back(
APValue(f));
6642 return Success(Elements, E);
6646 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
6650 if (EltTy->isIntegerType())
6651 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
6654 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
6657 return Success(Elements, E);
6660 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
6662 return ZeroInitialization(E);
6670 class ArrayExprEvaluator
6671 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
6676 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
6677 : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
6681 "expected array or string literal");
6686 bool ZeroInitialization(
const Expr *E) {
6688 Info.Ctx.getAsConstantArrayType(E->
getType());
6693 CAT->
getSize().getZExtValue());
6694 if (!Result.hasArrayFiller())
return true;
6697 LValue Subobject = This;
6698 Subobject.addArray(Info, E, CAT);
6700 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
6703 bool VisitCallExpr(
const CallExpr *E) {
6704 return handleCallExpr(E, Result, &This);
6710 const LValue &Subobject,
6716 APValue &Result, EvalInfo &Info) {
6718 return ArrayExprEvaluator(Info, This, Result).Visit(E);
6721 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6734 return Success(Val, E);
6737 bool Success =
true;
6739 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
6740 "zero-initialized array shouldn't have any initialized elts");
6742 if (Result.isArray() && Result.hasArrayFiller())
6746 unsigned NumElts = CAT->
getSize().getZExtValue();
6751 if (NumEltsToInit != NumElts && !isa<ImplicitValueInitExpr>(FillerExpr))
6752 NumEltsToInit = NumElts;
6759 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I !=
E; ++
I)
6760 Result.getArrayInitializedElt(I) = Filler;
6761 if (Result.hasArrayFiller())
6765 LValue Subobject = This;
6766 Subobject.addArray(Info, E, CAT);
6767 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
6771 Info, Subobject, Init) ||
6774 if (!Info.noteFailure())
6780 if (!Result.hasArrayFiller())
6785 assert(FillerExpr &&
"no array filler for incomplete init list");
6787 FillerExpr) && Success;
6798 uint64_t Elements = CAT->
getSize().getZExtValue();
6801 LValue Subobject = This;
6802 Subobject.addArray(Info, E, CAT);
6804 bool Success =
true;
6805 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
6810 if (!Info.noteFailure())
6819 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
6820 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
6824 const LValue &Subobject,
6827 bool HadZeroInit = !Value->
isUninit();
6830 unsigned N = CAT->
getSize().getZExtValue();
6840 for (
unsigned I = 0; I != N; ++
I)
6844 LValue ArrayElt = Subobject;
6845 ArrayElt.addArray(Info, E, CAT);
6846 for (
unsigned I = 0; I != N; ++
I)
6859 return RecordExprEvaluator(Info, Subobject, *Value)
6860 .VisitCXXConstructExpr(E, Type);
6872 class IntExprEvaluator
6873 :
public ExprEvaluatorBase<IntExprEvaluator> {
6876 IntExprEvaluator(EvalInfo &info,
APValue &result)
6877 : ExprEvaluatorBaseTy(info), Result(result) {}
6879 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
6881 "Invalid evaluation result.");
6883 "Invalid evaluation result.");
6884 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
6885 "Invalid evaluation result.");
6889 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
6890 return Success(SI, E, Result);
6893 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
6895 "Invalid evaluation result.");
6896 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
6897 "Invalid evaluation result.");
6899 Result.
getInt().setIsUnsigned(
6903 bool Success(
const llvm::APInt &I,
const Expr *E) {
6904 return Success(I, E, Result);
6907 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
6909 "Invalid evaluation result.");
6913 bool Success(uint64_t Value,
const Expr *E) {
6914 return Success(Value, E, Result);
6926 return Success(V.
getInt(),
E);
6929 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
6942 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
6944 if (CheckReferencedDecl(E, E->
getDecl()))
6947 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
6951 VisitIgnoredBaseExpression(E->
getBase());
6955 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
6958 bool VisitCallExpr(
const CallExpr *E);
6959 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
6964 bool VisitCastExpr(
const CastExpr* E);
6976 if (Info.ArrayInitIndex == uint64_t(-1)) {
6982 return Success(Info.ArrayInitIndex, E);
6987 return ZeroInitialization(E);
7023 return IntExprEvaluator(Info, Result).Visit(E);
7033 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
7043 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
7047 bool SameSign = (ECD->getInitVal().isSigned()
7049 bool SameWidth = (ECD->getInitVal().getBitWidth()
7050 == Info.Ctx.getIntWidth(E->
getType()));
7051 if (SameSign && SameWidth)
7052 return Success(ECD->getInitVal(),
E);
7056 llvm::APSInt Val = ECD->getInitVal();
7058 Val.setIsSigned(!ECD->getInitVal().isSigned());
7060 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
7061 return Success(Val, E);
7073 enum gcc_type_class {
7075 void_type_class, integer_type_class, char_type_class,
7076 enumeral_type_class, boolean_type_class,
7077 pointer_type_class, reference_type_class, offset_type_class,
7078 real_type_class, complex_type_class,
7079 function_type_class, method_type_class,
7080 record_type_class, union_type_class,
7081 array_type_class, string_type_class,
7088 return no_type_class;
7094 #define TYPE(ID, BASE)
7095 #define DEPENDENT_TYPE(ID, BASE) case Type::ID:
7096 #define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
7097 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
7098 #include "clang/AST/TypeNodes.def"
7099 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
7103 #define BUILTIN_TYPE(ID, SINGLETON_ID)
7104 #define SIGNED_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: return integer_type_class;
7105 #define FLOATING_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: return real_type_class;
7106 #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: break;
7107 #include "clang/AST/BuiltinTypes.def"
7108 case BuiltinType::Void:
7109 return void_type_class;
7111 case BuiltinType::Bool:
7112 return boolean_type_class;
7114 case BuiltinType::Char_U:
7115 case BuiltinType::UChar:
7116 case BuiltinType::UShort:
7117 case BuiltinType::UInt:
7118 case BuiltinType::ULong:
7119 case BuiltinType::ULongLong:
7120 case BuiltinType::UInt128:
7121 return integer_type_class;
7123 case BuiltinType::NullPtr:
7124 return pointer_type_class;
7126 case BuiltinType::WChar_U:
7127 case BuiltinType::Char16:
7128 case BuiltinType::Char32:
7129 case BuiltinType::ObjCId:
7130 case BuiltinType::ObjCClass:
7131 case BuiltinType::ObjCSel:
7132 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
7133 case BuiltinType::Id:
7134 #include "clang/Basic/OpenCLImageTypes.def"
7135 case BuiltinType::OCLSampler:
7136 case BuiltinType::OCLEvent:
7137 case BuiltinType::OCLClkEvent:
7138 case BuiltinType::OCLQueue:
7139 case BuiltinType::OCLReserveID:
7140 case BuiltinType::Dependent:
7141 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
7145 return LangOpts.CPlusPlus ? enumeral_type_class : integer_type_class;
7149 return pointer_type_class;
7152 case Type::MemberPointer:
7154 return offset_type_class;
7159 return method_type_class;
7163 return complex_type_class;
7165 case Type::FunctionNoProto:
7166 case Type::FunctionProto:
7167 return LangOpts.CPlusPlus ? function_type_class : pointer_type_class;
7171 switch (RT->getDecl()->getTagKind()) {
7175 return record_type_class;
7178 return LangOpts.CPlusPlus ? enumeral_type_class : integer_type_class;
7181 return union_type_class;
7184 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
7186 case Type::ConstantArray:
7187 case Type::VariableArray:
7188 case Type::IncompleteArray:
7189 return LangOpts.CPlusPlus ? array_type_class : pointer_type_class;
7191 case Type::BlockPointer:
7192 case Type::LValueReference:
7193 case Type::RValueReference:
7195 case Type::ExtVector:
7197 case Type::DeducedTemplateSpecialization:
7198 case Type::ObjCObject:
7199 case Type::ObjCInterface:
7200 case Type::ObjCObjectPointer:
7203 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
7206 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
7214 template<
typename LValue>
7216 const Expr *E = LV.getLValueBase().template dyn_cast<
const Expr*>();
7217 return E && isa<StringLiteral>(
E) && LV.getLValueOffset().isZero();
7244 if (V.
getKind() == APValue::Int)
7246 if (V.
getKind() == APValue::LValue)
7253 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
7268 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
7270 }
else if (
const Expr *E = B.get<
const Expr*>()) {
7271 if (isa<CompoundLiteralExpr>(E))
7288 auto *Cast = dyn_cast<
CastExpr>(NoParens);
7289 if (Cast ==
nullptr)
7296 CastKind != CK_AddressSpaceConversion)
7299 auto *SubExpr = Cast->getSubExpr();
7320 assert(!LVal.Designator.Invalid);
7322 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &Invalid) {
7325 if (Invalid || Parent->
isUnion())
7331 auto &Base = LVal.getLValueBase();
7332 if (
auto *ME = dyn_cast_or_null<MemberExpr>(Base.dyn_cast<
const Expr *>())) {
7333 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
7335 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
7337 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
7338 for (
auto *FD : IFD->chain()) {
7340 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid))
7348 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
7349 assert(isBaseAnAllocSizeCall(Base) &&
7350 "Unsized array in non-alloc_size call?");
7356 for (
unsigned E = LVal.Designator.Entries.size(); I !=
E; ++
I) {
7357 const auto &Entry = LVal.Designator.Entries[
I];
7363 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
7364 uint64_t Index = Entry.ArrayIndex;
7365 if (Index + 1 != CAT->
getSize())
7370 uint64_t Index = Entry.ArrayIndex;
7374 }
else if (
auto *FD = getAsField(Entry)) {
7376 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
7380 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
7392 if (LVal.Designator.Invalid)
7395 if (!LVal.Designator.Entries.empty())
7396 return LVal.Designator.isMostDerivedAnUnsizedArray();
7398 if (!LVal.InvalidBase)
7403 const auto *E = LVal.Base.dyn_cast<
const Expr *>();
7404 return !E || !isa<MemberExpr>(
E);
7410 const SubobjectDesignator &
Designator = LVal.Designator;
7422 return LVal.InvalidBase &&
7423 Designator.Entries.size() == Designator.MostDerivedPathLength &&
7424 Designator.MostDerivedIsArrayElement &&
7433 if (Int.ugt(CharUnitsMax))
7435 Result = CharUnits::fromQuantity(Int.getZExtValue());
7446 unsigned Type,
const LValue &LVal,
7459 if (!(Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
7461 if (Type == 3 && !DetermineForCompleteObject)
7464 llvm::APInt APEndOffset;
7465 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
7469 if (LVal.InvalidBase)
7473 return CheckedHandleSizeof(BaseTy, EndOffset);
7477 const SubobjectDesignator &
Designator = LVal.Designator;
7489 llvm::APInt APEndOffset;
7490 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
7502 if (!CheckedHandleSizeof(Designator.MostDerivedType, BytesPerElem))
7508 int64_t ElemsRemaining;
7509 if (Designator.MostDerivedIsArrayElement &&
7510 Designator.Entries.size() == Designator.MostDerivedPathLength) {
7511 uint64_t ArraySize = Designator.getMostDerivedArraySize();
7512 uint64_t ArrayIndex = Designator.Entries.back().ArrayIndex;
7513 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
7515 ElemsRemaining = Designator.isOnePastTheEnd() ? 0 : 1;
7518 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
7528 EvalInfo &Info, uint64_t &Size) {
7535 SpeculativeEvaluationRAII SpeculativeEval(Info);
7536 FoldOffsetRAII Fold(Info);
7544 LVal.setFrom(Info.Ctx, RVal);
7552 if (LVal.getLValueOffset().isNegative()) {
7563 if (EndOffset <= LVal.getLValueOffset())
7566 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
7570 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
7572 return VisitBuiltinCallExpr(E, BuiltinOp);
7574 return ExprEvaluatorBaseTy::VisitCallExpr(E);
7577 bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
7578 unsigned BuiltinOp) {
7581 return ExprEvaluatorBaseTy::VisitCallExpr(E);
7583 case Builtin::BI__builtin_object_size: {
7587 assert(Type <= 3 &&
"unexpected type");
7591 return Success(Size, E);
7594 return Success((Type & 2) ? 0 : -1,
E);
7598 switch (Info.EvalMode) {
7599 case EvalInfo::EM_ConstantExpression:
7600 case EvalInfo::EM_PotentialConstantExpression:
7601 case EvalInfo::EM_ConstantFold:
7602 case EvalInfo::EM_EvaluateForOverflow:
7603 case EvalInfo::EM_IgnoreSideEffects:
7604 case EvalInfo::EM_OffsetFold:
7607 case EvalInfo::EM_ConstantExpressionUnevaluated:
7608 case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
7610 return Success((Type & 2) ? 0 : -1, E);
7613 llvm_unreachable(
"unexpected EvalMode");
7616 case Builtin::BI__builtin_bswap16:
7617 case Builtin::BI__builtin_bswap32:
7618 case Builtin::BI__builtin_bswap64: {
7623 return Success(Val.byteSwap(),
E);
7626 case Builtin::BI__builtin_classify_type:
7633 case Builtin::BI__builtin_clz:
7634 case Builtin::BI__builtin_clzl:
7635 case Builtin::BI__builtin_clzll:
7636 case Builtin::BI__builtin_clzs: {
7643 return Success(Val.countLeadingZeros(),
E);
7646 case Builtin::BI__builtin_constant_p:
7649 case Builtin::BI__builtin_ctz:
7650 case Builtin::BI__builtin_ctzl:
7651 case Builtin::BI__builtin_ctzll:
7652 case Builtin::BI__builtin_ctzs: {
7659 return Success(Val.countTrailingZeros(),
E);
7662 case Builtin::BI__builtin_eh_return_data_regno: {
7664 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
7665 return Success(Operand, E);
7668 case Builtin::BI__builtin_expect:
7669 return Visit(E->
getArg(0));
7671 case Builtin::BI__builtin_ffs:
7672 case Builtin::BI__builtin_ffsl:
7673 case Builtin::BI__builtin_ffsll: {
7678 unsigned N = Val.countTrailingZeros();
7679 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
7682 case Builtin::BI__builtin_fpclassify: {
7687 switch (Val.getCategory()) {
7688 case APFloat::fcNaN: Arg = 0;
break;
7689 case APFloat::fcInfinity: Arg = 1;
break;
7690 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
7691 case APFloat::fcZero: Arg = 4;
break;
7693 return Visit(E->
getArg(Arg));
7696 case Builtin::BI__builtin_isinf_sign: {
7699 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
7702 case Builtin::BI__builtin_isinf: {
7705 Success(Val.isInfinity() ? 1 : 0,
E);
7708 case Builtin::BI__builtin_isfinite: {
7711 Success(Val.isFinite() ? 1 : 0,
E);
7714 case Builtin::BI__builtin_isnan: {
7717 Success(Val.isNaN() ? 1 : 0,
E);
7720 case Builtin::BI__builtin_isnormal: {
7723 Success(Val.isNormal() ? 1 : 0,
E);
7726 case Builtin::BI__builtin_parity:
7727 case Builtin::BI__builtin_parityl:
7728 case Builtin::BI__builtin_parityll: {
7733 return Success(Val.countPopulation() % 2,
E);
7736 case Builtin::BI__builtin_popcount:
7737 case Builtin::BI__builtin_popcountl:
7738 case Builtin::BI__builtin_popcountll: {
7743 return Success(Val.countPopulation(),
E);
7746 case Builtin::BIstrlen:
7747 case Builtin::BIwcslen:
7749 if (Info.getLangOpts().CPlusPlus11)
7750 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
7752 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
7754 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
7756 case Builtin::BI__builtin_strlen:
7757 case Builtin::BI__builtin_wcslen: {
7767 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
7768 String.getLValueBase().dyn_cast<
const Expr *>())) {
7771 StringRef Str = S->getBytes();
7772 int64_t Off = String.Offset.getQuantity();
7773 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
7774 S->getCharByteWidth() == 1 &&
7776 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
7777 Str = Str.substr(Off);
7779 StringRef::size_type Pos = Str.find(0);
7780 if (Pos != StringRef::npos)
7781 Str = Str.substr(0, Pos);
7783 return Success(Str.size(),
E);
7790 for (uint64_t Strlen = 0; ; ++Strlen) {
7796 return Success(Strlen, E);
7802 case Builtin::BIstrcmp:
7803 case Builtin::BIwcscmp:
7804 case Builtin::BIstrncmp:
7805 case Builtin::BIwcsncmp:
7806 case Builtin::BImemcmp:
7807 case Builtin::BIwmemcmp:
7809 if (Info.getLangOpts().CPlusPlus11)
7810 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
7812 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
7814 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
7816 case Builtin::BI__builtin_strcmp:
7817 case Builtin::BI__builtin_wcscmp:
7818 case Builtin::BI__builtin_strncmp:
7819 case Builtin::BI__builtin_wcsncmp:
7820 case Builtin::BI__builtin_memcmp:
7821 case Builtin::BI__builtin_wmemcmp: {
7822 LValue String1, String2;
7829 uint64_t MaxLength = uint64_t(-1);
7830 if (BuiltinOp != Builtin::BIstrcmp &&
7831 BuiltinOp != Builtin::BIwcscmp &&
7832 BuiltinOp != Builtin::BI__builtin_strcmp &&
7833 BuiltinOp != Builtin::BI__builtin_wcscmp) {
7837 MaxLength = N.getExtValue();
7839 bool StopAtNull = (BuiltinOp != Builtin::BImemcmp &&
7840 BuiltinOp != Builtin::BIwmemcmp &&
7841 BuiltinOp != Builtin::BI__builtin_memcmp &&
7842 BuiltinOp != Builtin::BI__builtin_wmemcmp);
7843 for (; MaxLength; --MaxLength) {
7850 return Success(Char1.
getInt() < Char2.
getInt() ? -1 : 1,
E);
7851 if (StopAtNull && !Char1.
getInt())
7852 return Success(0, E);
7853 assert(!(StopAtNull && !Char2.
getInt()));
7859 return Success(0, E);
7862 case Builtin::BI__atomic_always_lock_free:
7863 case Builtin::BI__atomic_is_lock_free:
7864 case Builtin::BI__c11_atomic_is_lock_free: {
7879 CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
7882 unsigned InlineWidthBits =
7883 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
7884 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
7885 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
7886 Size == CharUnits::One() ||
7888 Expr::NPC_NeverValueDependent))
7891 return Success(1, E);
7894 castAs<PointerType>()->getPointeeType();
7896 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
7898 return Success(1, E);
7903 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
7904 Success(0, E) :
Error(E);
7910 if (!A.getLValueBase())
7911 return !B.getLValueBase();
7912 if (!B.getLValueBase())
7915 if (A.getLValueBase().getOpaqueValue() !=
7916 B.getLValueBase().getOpaqueValue()) {
7926 A.getLValueCallIndex() == B.getLValueCallIndex();
7935 if (!LV.getLValueBase())
7940 if (!LV.getLValueDesignator().Invalid &&
7941 !LV.getLValueDesignator().isOnePastTheEnd())
7946 QualType Ty = getType(LV.getLValueBase());
7953 return LV.getLValueOffset() == Size;
7963 class DataRecursiveIntBinOpEvaluator {
7968 EvalResult() : Failed(false) { }
7970 void swap(EvalResult &RHS) {
7972 Failed = RHS.Failed;
7979 EvalResult LHSResult;
7980 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
7983 Job(Job &&) =
default;
7985 void startSpeculativeEval(EvalInfo &Info) {
7986 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
7990 SpeculativeEvaluationRAII SpecEvalRAII;
7995 IntExprEvaluator &IntEval;
8000 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
8001 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
8018 EvalResult PrevResult;
8019 while (!Queue.empty())
8020 process(PrevResult);
8022 if (PrevResult.Failed)
return false;
8024 FinalResult.swap(PrevResult.Val);
8029 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
8030 return IntEval.Success(Value, E, Result);
8032 bool Success(
const APSInt &Value,
const Expr *E,
APValue &Result) {
8033 return IntEval.Success(Value, E, Result);
8036 return IntEval.Error(E);
8039 return IntEval.Error(E, D);
8043 return Info.CCEDiag(E, D);
8047 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
8048 bool &SuppressRHSDiags);
8050 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
8053 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
8054 Result.Failed = !
Evaluate(Result.Val, Info, E);
8059 void process(EvalResult &Result);
8061 void enqueue(
const Expr *E) {
8063 Queue.resize(Queue.size()+1);
8065 Queue.back().Kind = Job::AnyExprKind;
8071 bool DataRecursiveIntBinOpEvaluator::
8072 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
8073 bool &SuppressRHSDiags) {
8076 if (LHSResult.Failed)
8077 return Info.noteSideEffect();
8086 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
8087 Success(LHSAsBool, E, LHSResult.Val);
8091 LHSResult.Failed =
true;
8095 if (!Info.noteSideEffect())
8101 SuppressRHSDiags =
true;
8110 if (LHSResult.Failed && !Info.noteFailure())
8121 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
8124 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
8125 Offset = CharUnits::fromQuantity(IsSub ? Offset64 - Index64
8126 : Offset64 + Index64);
8129 bool DataRecursiveIntBinOpEvaluator::
8130 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
8133 if (RHSResult.Failed)
8135 Result = RHSResult.Val;
8140 bool lhsResult, rhsResult;
8147 return Success(lhsResult || rhsResult, E, Result);
8149 return Success(lhsResult && rhsResult, E, Result);
8155 if (rhsResult == (E->
getOpcode() == BO_LOr))
8156 return Success(rhsResult, E, Result);
8166 if (LHSResult.Failed || RHSResult.Failed)
8169 const APValue &LHSVal = LHSResult.Val;
8170 const APValue &RHSVal = RHSResult.Val;
8194 if (!LHSExpr || !RHSExpr)
8198 if (!LHSAddrExpr || !RHSAddrExpr)
8202 RHSAddrExpr->getLabel()->getDeclContext())
8204 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
8220 return Success(Value, E, Result);
8223 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
8224 Job &job = Queue.back();
8227 case Job::AnyExprKind: {
8228 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
8229 if (shouldEnqueue(Bop)) {
8230 job.Kind = Job::BinOpKind;
8231 enqueue(Bop->getLHS());
8236 EvaluateExpr(job.E, Result);
8241 case Job::BinOpKind: {
8243 bool SuppressRHSDiags =
false;
8244 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
8248 if (SuppressRHSDiags)
8249 job.startSpeculativeEval(Info);
8250 job.LHSResult.swap(Result);
8251 job.Kind = Job::BinOpVisitedLHSKind;
8256 case Job::BinOpVisitedLHSKind: {
8260 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
8266 llvm_unreachable(
"Invalid Job::Kind!");
8272 class DelayedNoteFailureRAII {
8277 DelayedNoteFailureRAII(EvalInfo &Info,
bool NoteFailure =
true)
8278 : Info(Info), NoteFailure(NoteFailure) {}
8279 ~DelayedNoteFailureRAII() {
8281 bool ContinueAfterFailure = Info.noteFailure();
8282 (void)ContinueAfterFailure;
8283 assert(ContinueAfterFailure &&
8284 "Shouldn't have kept evaluating on failure.");
8290 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
8296 DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->
isAssignmentOp());
8297 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
8298 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
8304 ComplexValue LHS, RHS;
8313 LHS.makeComplexFloat();
8314 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
8319 if (!LHSOK && !Info.noteFailure())
8325 RHS.makeComplexFloat();
8326 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
8330 if (LHS.isComplexFloat()) {
8331 APFloat::cmpResult CR_r =
8332 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
8333 APFloat::cmpResult CR_i =
8334 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
8337 return Success((CR_r == APFloat::cmpEqual &&
8338 CR_i == APFloat::cmpEqual),
E);
8341 "Invalid complex comparison.");
8342 return Success(((CR_r == APFloat::cmpGreaterThan ||
8343 CR_r == APFloat::cmpLessThan ||
8344 CR_r == APFloat::cmpUnordered) ||
8345 (CR_i == APFloat::cmpGreaterThan ||
8346 CR_i == APFloat::cmpLessThan ||
8347 CR_i == APFloat::cmpUnordered)), E);
8351 return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
8352 LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
8355 "Invalid compex comparison.");
8356 return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
8357 LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
8364 APFloat RHS(0.0), LHS(0.0);
8367 if (!LHSOK && !Info.noteFailure())
8373 APFloat::cmpResult CR = LHS.compare(RHS);
8377 llvm_unreachable(
"Invalid binary operator!");
8379 return Success(CR == APFloat::cmpLessThan, E);
8381 return Success(CR == APFloat::cmpGreaterThan, E);
8383 return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
8385 return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
8388 return Success(CR == APFloat::cmpEqual, E);
8390 return Success(CR == APFloat::cmpGreaterThan
8391 || CR == APFloat::cmpLessThan
8392 || CR == APFloat::cmpUnordered, E);
8398 LValue LHSValue, RHSValue;
8401 if (!LHSOK && !Info.noteFailure())
8412 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
8414 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr*>();
8415 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr*>();
8416 if (!LHSExpr || !RHSExpr)
8420 if (!LHSAddrExpr || !RHSAddrExpr)
8424 RHSAddrExpr->getLabel()->getDeclContext())
8426 return Success(
APValue(LHSAddrExpr, RHSAddrExpr), E);
8435 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
8436 (!RHSValue.Base && !RHSValue.Offset.isZero()))
8443 LHSValue.Base && RHSValue.Base)
8451 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
8453 (RHSValue.Base && RHSValue.Offset.isZero() &&
8468 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
8469 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
8471 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
8472 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
8479 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
8481 LHSDesignator, RHSDesignator))
8482 CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
8494 if (ElementSize.
isZero()) {
8495 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
8509 llvm::APInt(65, (int64_t)LHSOffset.
getQuantity(),
true),
false);
8511 llvm::APInt(65, (int64_t)RHSOffset.
getQuantity(),
true),
false);
8513 llvm::APInt(65, (int64_t)ElementSize.
getQuantity(),
true),
false);
8514 APSInt TrueResult = (LHS - RHS) / ElemSize;
8515 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
8517 if (Result.extend(65) != TrueResult &&
8520 return Success(Result, E);
8532 CCEDiag(E, diag::note_constexpr_void_comparison);
8542 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
8547 RHSDesignator, WasArrayIndex);
8554 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
8555 Mismatch < RHSDesignator.Entries.size()) {
8556 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
8557 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
8559 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
8561 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
8562 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
8565 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
8566 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
8570 CCEDiag(E, diag::note_constexpr_pointer_comparison_differing_access)
8578 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
8581 assert(PtrSize <= 64 &&
"Unexpected pointer width");
8582 uint64_t Mask = ~0ULL >> (64 - PtrSize);
8590 QualType BaseTy = getType(LHSValue.Base);
8593 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
8595 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
8600 default: llvm_unreachable(
"missing comparison operator");
8601 case BO_LT:
return Success(CompareLHS < CompareRHS, E);
8602 case BO_GT:
return Success(CompareLHS > CompareRHS, E);
8603 case BO_LE:
return Success(CompareLHS <= CompareRHS, E);
8604 case BO_GE:
return Success(CompareLHS >= CompareRHS, E);
8605 case BO_EQ:
return Success(CompareLHS == CompareRHS, E);
8606 case BO_NE:
return Success(CompareLHS != CompareRHS, E);
8612 assert(E->
isEqualityOp() &&
"unexpected member pointer operation");
8615 MemberPtr LHSValue, RHSValue;
8618 if (!LHSOK && !Info.noteFailure())
8627 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
8628 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
8629 return Success(E->
getOpcode() == BO_EQ ? Equal : !Equal,
E);
8634 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
8635 if (MD->isVirtual())
8636 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
8637 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
8638 if (MD->isVirtual())
8639 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
8645 bool Equal = LHSValue == RHSValue;
8646 return Success(E->
getOpcode() == BO_EQ ? Equal : !Equal,
E);
8651 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
8656 return Success(Opcode == BO_EQ || Opcode == BO_LE || Opcode == BO_GE, E);
8661 "DataRecursiveIntBinOpEvaluator should have handled integral types");
8663 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8668 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
8689 return Success(n, E);
8691 return Success(1, E);
8704 return Success(Sizeof, E);
8709 Info.Ctx.toCharUnitsFromBits(
8715 llvm_unreachable(
"unknown expr/type trait");
8718 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
8724 for (
unsigned i = 0; i != n; ++i) {
8727 case OffsetOfNode::Array: {
8732 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
8736 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
8737 Result += IdxResult.getSExtValue() * ElementSize;
8741 case OffsetOfNode::Field: {
8750 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
8756 case OffsetOfNode::Identifier:
8757 llvm_unreachable(
"dependent __builtin_offsetof");
8759 case OffsetOfNode::Base: {
8773 CurrentType = BaseSpec->
getType();
8784 return Success(Result, OOE);
8787 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
8803 if (!Result.isInt())
return Error(E);
8804 const APSInt &Value = Result.getInt();
8805 if (Value.isSigned() && Value.isMinSignedValue() &&
8809 return Success(-Value, E);
8814 if (!Result.isInt())
return Error(E);
8815 return Success(~Result.getInt(),
E);
8821 return Success(!bres, E);
8828 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8834 case CK_BaseToDerived:
8835 case CK_DerivedToBase:
8836 case CK_UncheckedDerivedToBase:
8839 case CK_ArrayToPointerDecay:
8840 case CK_FunctionToPointerDecay:
8841 case CK_NullToPointer:
8842 case CK_NullToMemberPointer:
8843 case CK_BaseToDerivedMemberPointer:
8844 case CK_DerivedToBaseMemberPointer:
8845 case CK_ReinterpretMemberPointer:
8846 case CK_ConstructorConversion:
8847 case CK_IntegralToPointer:
8849 case CK_VectorSplat:
8850 case CK_IntegralToFloating:
8851 case CK_FloatingCast:
8852 case CK_CPointerToObjCPointerCast:
8853 case CK_BlockPointerToObjCPointerCast:
8854 case CK_AnyPointerToBlockPointerCast:
8855 case CK_ObjCObjectLValueCast:
8856 case CK_FloatingRealToComplex:
8857 case CK_FloatingComplexToReal:
8858 case CK_FloatingComplexCast:
8859 case CK_FloatingComplexToIntegralComplex:
8860 case CK_IntegralRealToComplex:
8861 case CK_IntegralComplexCast:
8862 case CK_IntegralComplexToFloatingComplex:
8863 case CK_BuiltinFnToFnPtr:
8864 case CK_ZeroToOCLEvent:
8865 case CK_ZeroToOCLQueue:
8866 case CK_NonAtomicToAtomic:
8867 case CK_AddressSpaceConversion:
8868 case CK_IntToOCLSampler:
8869 llvm_unreachable(
"invalid cast kind for integral value");
8873 case CK_LValueBitCast:
8874 case CK_ARCProduceObject:
8875 case CK_ARCConsumeObject:
8876 case CK_ARCReclaimReturnedObject:
8877 case CK_ARCExtendBlockObject:
8878 case CK_CopyAndAutoreleaseBlockObject:
8881 case CK_UserDefinedConversion:
8882 case CK_LValueToRValue:
8883 case CK_AtomicToNonAtomic:
8885 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8887 case CK_MemberPointerToBoolean:
8888 case CK_PointerToBoolean:
8889 case CK_IntegralToBoolean:
8890 case CK_FloatingToBoolean:
8891 case CK_BooleanToSignedIntegral:
8892 case CK_FloatingComplexToBoolean:
8893 case CK_IntegralComplexToBoolean: {
8897 uint64_t IntResult = BoolResult;
8898 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
8899 IntResult = (uint64_t)-1;
8900 return Success(IntResult, E);
8903 case CK_IntegralCast: {
8904 if (!Visit(SubExpr))
8907 if (!Result.isInt()) {
8913 if (Result.isAddrLabelDiff())
8914 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
8916 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
8920 Result.getInt()), E);
8923 case CK_PointerToIntegral: {
8924 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
8930 if (LV.getLValueBase()) {
8935 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
8938 LV.Designator.setInvalid();
8939 LV.moveInto(Result);
8944 if (LV.isNullPointer())
8945 V = Info.Ctx.getTargetNullPointerValue(SrcType);
8947 V = LV.getLValueOffset().getQuantity();
8949 APSInt AsInt = Info.Ctx.MakeIntValue(V, SrcType);
8953 case CK_IntegralComplexToReal: {
8957 return Success(C.getComplexIntReal(),
E);
8960 case CK_FloatingToIntegral: {
8968 return Success(Value, E);
8972 llvm_unreachable(
"unknown cast resulting in integral value");
8975 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
8980 if (!LV.isComplexInt())
8982 return Success(LV.getComplexIntReal(),
E);
8988 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
8993 if (!LV.isComplexInt())
8995 return Success(LV.getComplexIntImag(),
E);
8999 return Success(0, E);
9002 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
9006 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
9015 class FloatExprEvaluator
9016 :
public ExprEvaluatorBase<FloatExprEvaluator> {
9019 FloatExprEvaluator(EvalInfo &info, APFloat &result)
9020 : ExprEvaluatorBaseTy(info), Result(result) {}
9027 bool ZeroInitialization(
const Expr *E) {
9028 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
9032 bool VisitCallExpr(
const CallExpr *E);
9037 bool VisitCastExpr(
const CastExpr *E);
9048 return FloatExprEvaluator(Info, Result).Visit(E);
9055 llvm::APFloat &Result) {
9057 if (!S)
return false;
9065 fill = llvm::APInt(32, 0);
9066 else if (S->
getString().getAsInteger(0, fill))
9071 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
9073 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
9081 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
9083 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
9089 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9092 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9094 case Builtin::BI__builtin_huge_val:
9095 case Builtin::BI__builtin_huge_valf:
9096 case Builtin::BI__builtin_huge_vall:
9097 case Builtin::BI__builtin_inf:
9098 case Builtin::BI__builtin_inff:
9099 case Builtin::BI__builtin_infl: {
9100 const llvm::fltSemantics &Sem =
9101 Info.Ctx.getFloatTypeSemantics(E->
getType());
9102 Result = llvm::APFloat::getInf(Sem);
9106 case Builtin::BI__builtin_nans:
9107 case Builtin::BI__builtin_nansf:
9108 case Builtin::BI__builtin_nansl:
9114 case Builtin::BI__builtin_nan:
9115 case Builtin::BI__builtin_nanf:
9116 case Builtin::BI__builtin_nanl:
9124 case Builtin::BI__builtin_fabs:
9125 case Builtin::BI__builtin_fabsf:
9126 case Builtin::BI__builtin_fabsl:
9130 if (Result.isNegative())
9131 Result.changeSign();
9138 case Builtin::BI__builtin_copysign:
9139 case Builtin::BI__builtin_copysignf:
9140 case Builtin::BI__builtin_copysignl: {
9145 Result.copySign(RHS);
9151 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9156 Result = CV.FloatReal;
9163 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9168 Result = CV.FloatImag;
9173 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
9174 Result = llvm::APFloat::getZero(Sem);
9178 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
9180 default:
return Error(E);
9186 Result.changeSign();
9191 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9193 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9197 if (!LHSOK && !Info.noteFailure())
9203 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
9208 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9213 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9215 case CK_IntegralToFloating: {
9222 case CK_FloatingCast: {
9223 if (!Visit(SubExpr))
9229 case CK_FloatingComplexToReal: {
9233 Result = V.getComplexFloatReal();
9244 class ComplexExprEvaluator
9245 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
9249 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
9250 : ExprEvaluatorBaseTy(info), Result(Result) {}
9257 bool ZeroInitialization(
const Expr *E);
9264 bool VisitCastExpr(
const CastExpr *E);
9274 return ComplexExprEvaluator(Info, Result).Visit(E);
9277 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
9280 Result.makeComplexFloat();
9281 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
9282 Result.FloatReal = Zero;
9283 Result.FloatImag = Zero;
9285 Result.makeComplexInt();
9286 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
9287 Result.IntReal = Zero;
9288 Result.IntImag = Zero;
9293 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
9297 Result.makeComplexFloat();
9298 APFloat &Imag = Result.FloatImag;
9302 Result.FloatReal = APFloat(Imag.getSemantics());
9306 "Unexpected imaginary literal.");
9308 Result.makeComplexInt();
9309 APSInt &Imag = Result.IntImag;
9313 Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
9318 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9322 case CK_BaseToDerived:
9323 case CK_DerivedToBase:
9324 case CK_UncheckedDerivedToBase:
9327 case CK_ArrayToPointerDecay:
9328 case CK_FunctionToPointerDecay:
9329 case CK_NullToPointer:
9330 case CK_NullToMemberPointer:
9331 case CK_BaseToDerivedMemberPointer:
9332 case CK_DerivedToBaseMemberPointer:
9333 case CK_MemberPointerToBoolean:
9334 case CK_ReinterpretMemberPointer:
9335 case CK_ConstructorConversion:
9336 case CK_IntegralToPointer:
9337 case CK_PointerToIntegral:
9338 case CK_PointerToBoolean:
9340 case CK_VectorSplat:
9341 case CK_IntegralCast:
9342 case CK_BooleanToSignedIntegral:
9343 case CK_IntegralToBoolean:
9344 case CK_IntegralToFloating:
9345 case CK_FloatingToIntegral:
9346 case CK_FloatingToBoolean:
9347 case CK_FloatingCast:
9348 case CK_CPointerToObjCPointerCast:
9349 case CK_BlockPointerToObjCPointerCast:
9350 case CK_AnyPointerToBlockPointerCast:
9351 case CK_ObjCObjectLValueCast:
9352 case CK_FloatingComplexToReal:
9353 case CK_FloatingComplexToBoolean:
9354 case CK_IntegralComplexToReal:
9355 case CK_IntegralComplexToBoolean:
9356 case CK_ARCProduceObject:
9357 case CK_ARCConsumeObject:
9358 case CK_ARCReclaimReturnedObject:
9359 case CK_ARCExtendBlockObject:
9360 case CK_CopyAndAutoreleaseBlockObject:
9361 case CK_BuiltinFnToFnPtr:
9362 case CK_ZeroToOCLEvent:
9363 case CK_ZeroToOCLQueue:
9364 case CK_NonAtomicToAtomic:
9365 case CK_AddressSpaceConversion:
9366 case CK_IntToOCLSampler:
9367 llvm_unreachable(
"invalid cast kind for complex value");
9369 case CK_LValueToRValue:
9370 case CK_AtomicToNonAtomic:
9372 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9375 case CK_LValueBitCast:
9376 case CK_UserDefinedConversion:
9379 case CK_FloatingRealToComplex: {
9380 APFloat &Real = Result.FloatReal;
9384 Result.makeComplexFloat();
9385 Result.FloatImag = APFloat(Real.getSemantics());
9389 case CK_FloatingComplexCast: {
9401 case CK_FloatingComplexToIntegralComplex: {
9408 Result.makeComplexInt();
9410 To, Result.IntReal) &&
9412 To, Result.IntImag);
9415 case CK_IntegralRealToComplex: {
9416 APSInt &Real = Result.IntReal;
9420 Result.makeComplexInt();
9421 Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
9425 case CK_IntegralComplexCast: {
9438 case CK_IntegralComplexToFloatingComplex: {
9445 Result.makeComplexFloat();
9447 To, Result.FloatReal) &&
9449 To, Result.FloatImag);
9453 llvm_unreachable(
"unknown cast resulting in complex value");
9456 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9458 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9462 bool LHSReal =
false, RHSReal =
false;
9467 APFloat &Real = Result.FloatReal;
9470 Result.makeComplexFloat();
9471 Result.FloatImag = APFloat(Real.getSemantics());
9474 LHSOK = Visit(E->
getLHS());
9476 if (!LHSOK && !Info.noteFailure())
9482 APFloat &Real = RHS.FloatReal;
9485 RHS.makeComplexFloat();
9486 RHS.FloatImag = APFloat(Real.getSemantics());
9490 assert(!(LHSReal && RHSReal) &&
9491 "Cannot have both operands of a complex operation be real.");
9493 default:
return Error(E);
9495 if (Result.isComplexFloat()) {
9496 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
9497 APFloat::rmNearestTiesToEven);
9499 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
9501 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
9502 APFloat::rmNearestTiesToEven);
9504 Result.getComplexIntReal() += RHS.getComplexIntReal();
9505 Result.getComplexIntImag() += RHS.getComplexIntImag();
9509 if (Result.isComplexFloat()) {
9510 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
9511 APFloat::rmNearestTiesToEven);
9513 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
9514 Result.getComplexFloatImag().changeSign();
9515 }
else if (!RHSReal) {
9516 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
9517 APFloat::rmNearestTiesToEven);
9520 Result.getComplexIntReal() -= RHS.getComplexIntReal();
9521 Result.getComplexIntImag() -= RHS.getComplexIntImag();
9525 if (Result.isComplexFloat()) {
9530 ComplexValue LHS =
Result;
9531 APFloat &A = LHS.getComplexFloatReal();
9532 APFloat &B = LHS.getComplexFloatImag();
9533 APFloat &C = RHS.getComplexFloatReal();
9534 APFloat &D = RHS.getComplexFloatImag();
9535 APFloat &ResR = Result.getComplexFloatReal();
9536 APFloat &ResI = Result.getComplexFloatImag();
9538 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
9541 }
else if (RHSReal) {
9553 if (ResR.isNaN() && ResI.isNaN()) {
9554 bool Recalc =
false;
9555 if (A.isInfinity() || B.isInfinity()) {
9556 A = APFloat::copySign(
9557 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
9558 B = APFloat::copySign(
9559 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
9561 C = APFloat::copySign(APFloat(C.getSemantics()), C);
9563 D = APFloat::copySign(APFloat(D.getSemantics()), D);
9566 if (C.isInfinity() || D.isInfinity()) {
9567 C = APFloat::copySign(
9568 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
9569 D = APFloat::copySign(
9570 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
9572 A = APFloat::copySign(APFloat(A.getSemantics()), A);
9574 B = APFloat::copySign(APFloat(B.getSemantics()), B);
9577 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
9578 AD.isInfinity() || BC.isInfinity())) {
9580 A = APFloat::copySign(APFloat(A.getSemantics()), A);
9582 B = APFloat::copySign(APFloat(B.getSemantics()), B);
9584 C = APFloat::copySign(APFloat(C.getSemantics()), C);
9586 D = APFloat::copySign(APFloat(D.getSemantics()), D);
9590 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
9591 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
9596 ComplexValue LHS =
Result;
9597 Result.getComplexIntReal() =
9598 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
9599 LHS.getComplexIntImag() * RHS.getComplexIntImag());
9600 Result.getComplexIntImag() =
9601 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
9602 LHS.getComplexIntImag() * RHS.getComplexIntReal());
9606 if (Result.isComplexFloat()) {
9611 ComplexValue LHS =
Result;
9612 APFloat &A = LHS.getComplexFloatReal();
9613 APFloat &B = LHS.getComplexFloatImag();
9614 APFloat &C = RHS.getComplexFloatReal();
9615 APFloat &D = RHS.getComplexFloatImag();
9616 APFloat &ResR = Result.getComplexFloatReal();
9617 APFloat &ResI = Result.getComplexFloatImag();
9624 B = APFloat::getZero(A.getSemantics());
9627 APFloat MaxCD = maxnum(
abs(C),
abs(D));
9628 if (MaxCD.isFinite()) {
9629 DenomLogB =
ilogb(MaxCD);
9630 C =
scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
9631 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
9633 APFloat Denom = C * C + D * D;
9634 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB,
9635 APFloat::rmNearestTiesToEven);
9636 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB,
9637 APFloat::rmNearestTiesToEven);
9638 if (ResR.isNaN() && ResI.isNaN()) {
9639 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
9640 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
9641 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
9642 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
9644 A = APFloat::copySign(
9645 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
9646 B = APFloat::copySign(
9647 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
9648 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
9649 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
9650 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
9651 C = APFloat::copySign(
9652 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
9653 D = APFloat::copySign(
9654 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
9655 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
9656 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
9661 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
9662 return Error(E, diag::note_expr_divide_by_zero);
9664 ComplexValue LHS =
Result;
9665 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
9666 RHS.getComplexIntImag() * RHS.getComplexIntImag();
9667 Result.getComplexIntReal() =
9668 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
9669 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
9670 Result.getComplexIntImag() =
9671 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
9672 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
9680 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
9694 if (Result.isComplexFloat()) {
9695 Result.getComplexFloatReal().changeSign();
9696 Result.getComplexFloatImag().changeSign();
9699 Result.getComplexIntReal() = -Result.getComplexIntReal();
9700 Result.getComplexIntImag() = -Result.getComplexIntImag();
9704 if (Result.isComplexFloat())
9705 Result.getComplexFloatImag().changeSign();
9707 Result.getComplexIntImag() = -Result.getComplexIntImag();
9712 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
9715 Result.makeComplexFloat();
9721 Result.makeComplexInt();
9729 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
9738 class AtomicExprEvaluator :
9739 public ExprEvaluatorBase<AtomicExprEvaluator> {
9743 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
9744 : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
9751 bool ZeroInitialization(
const Expr *E) {
9760 bool VisitCastExpr(
const CastExpr *E) {
9763 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9764 case CK_NonAtomicToAtomic:
9775 return AtomicExprEvaluator(Info, This, Result).Visit(E);
9784 class VoidExprEvaluator
9785 :
public ExprEvaluatorBase<VoidExprEvaluator> {
9787 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
9789 bool Success(
const APValue &V,
const Expr *e) {
return true; }
9791 bool ZeroInitialization(
const Expr *E) {
return true; }
9793 bool VisitCastExpr(
const CastExpr *E) {
9796 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9803 bool VisitCallExpr(
const CallExpr *E) {
9806 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9807 case Builtin::BI__assume:
9808 case Builtin::BI__builtin_assume:
9818 return VoidExprEvaluator(Info).Visit(E);
9833 LV.moveInto(Result);
9838 if (!IntExprEvaluator(Info, Result).Visit(E))
9844 LV.moveInto(Result);
9846 llvm::APFloat F(0.0);
9863 LV.set(E, Info.CurrentCall->Index);
9864 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
9870 LV.set(E, Info.CurrentCall->Index);
9871 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
9876 if (!Info.getLangOpts().CPlusPlus11)
9877 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
9885 LV.set(E, Info.CurrentCall->Index);
9886 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
9893 }
else if (Info.getLangOpts().CPlusPlus11) {
9894 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
9897 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
9908 const Expr *E,
bool AllowNonLiteralTypes) {
9947 LV.setFrom(Info.Ctx, Result);
9962 L->getType()->isUnsignedIntegerType()));
9996 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
10015 if (!
getType()->isIntegralOrEnumerationType())
10023 Result = ExprResult.Val.getInt();
10029 if (!
getType()->isRealFloatingType())
10037 Result = ExprResult.Val.getFloat();
10042 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
10050 LV.moveInto(Result.Val);
10064 EStatus.
Diag = &Notes;
10066 EvalInfo InitInfo(Ctx, EStatus, VD->
isConstexpr()
10067 ? EvalInfo::EM_ConstantExpression
10068 : EvalInfo::EM_ConstantFold);
10069 InitInfo.setEvaluatingDecl(VD, Value);
10106 EvalResult.Diag =
Diag;
10109 assert(Result &&
"Could not evaluate expression");
10110 assert(EvalResult.Val.isInt() &&
"Expression did not evaluate to integer");
10112 return EvalResult.Val.getInt();
10119 EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
10125 assert(Val.isLValue());
10153 IK_ICEIfUnevaluated,
10169 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
10181 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
10186 #define ABSTRACT_STMT(Node)
10187 #define STMT(Node, Base) case Expr::Node##Class:
10188 #define EXPR(Node, Base)
10189 #include "clang/AST/StmtNodes.inc"
10190 case Expr::PredefinedExprClass:
10191 case Expr::FloatingLiteralClass:
10192 case Expr::ImaginaryLiteralClass:
10193 case Expr::StringLiteralClass:
10194 case Expr::ArraySubscriptExprClass:
10195 case Expr::OMPArraySectionExprClass:
10196 case Expr::MemberExprClass:
10197 case Expr::CompoundAssignOperatorClass:
10198 case Expr::CompoundLiteralExprClass:
10199 case Expr::ExtVectorElementExprClass:
10200 case Expr::DesignatedInitExprClass:
10201 case Expr::ArrayInitLoopExprClass:
10202 case Expr::ArrayInitIndexExprClass:
10203 case Expr::NoInitExprClass:
10204 case Expr::DesignatedInitUpdateExprClass:
10205 case Expr::ImplicitValueInitExprClass:
10206 case Expr::ParenListExprClass:
10207 case Expr::VAArgExprClass:
10208 case Expr::AddrLabelExprClass:
10209 case Expr::StmtExprClass:
10210 case Expr::CXXMemberCallExprClass:
10211 case Expr::CUDAKernelCallExprClass:
10212 case Expr::CXXDynamicCastExprClass:
10213 case Expr::CXXTypeidExprClass:
10214 case Expr::CXXUuidofExprClass:
10215 case Expr::MSPropertyRefExprClass:
10216 case Expr::MSPropertySubscriptExprClass:
10217 case Expr::CXXNullPtrLiteralExprClass:
10218 case Expr::UserDefinedLiteralClass:
10219 case Expr::CXXThisExprClass:
10220 case Expr::CXXThrowExprClass:
10221 case Expr::CXXNewExprClass:
10222 case Expr::CXXDeleteExprClass:
10223 case Expr::CXXPseudoDestructorExprClass:
10224 case Expr::UnresolvedLookupExprClass:
10225 case Expr::TypoExprClass:
10226 case Expr::DependentScopeDeclRefExprClass:
10227 case Expr::CXXConstructExprClass:
10228 case Expr::CXXInheritedCtorInitExprClass:
10229 case Expr::CXXStdInitializerListExprClass:
10230 case Expr::CXXBindTemporaryExprClass:
10231 case Expr::ExprWithCleanupsClass:
10232 case Expr::CXXTemporaryObjectExprClass:
10233 case Expr::CXXUnresolvedConstructExprClass:
10234 case Expr::CXXDependentScopeMemberExprClass:
10235 case Expr::UnresolvedMemberExprClass:
10236 case Expr::ObjCStringLiteralClass:
10237 case Expr::ObjCBoxedExprClass:
10238 case Expr::ObjCArrayLiteralClass:
10239 case Expr::ObjCDictionaryLiteralClass:
10240 case Expr::ObjCEncodeExprClass:
10241 case Expr::ObjCMessageExprClass:
10242 case Expr::ObjCSelectorExprClass:
10243 case Expr::ObjCProtocolExprClass:
10244 case Expr::ObjCIvarRefExprClass:
10245 case Expr::ObjCPropertyRefExprClass:
10246 case Expr::ObjCSubscriptRefExprClass:
10247 case Expr::ObjCIsaExprClass:
10248 case Expr::ObjCAvailabilityCheckExprClass:
10249 case Expr::ShuffleVectorExprClass:
10250 case Expr::ConvertVectorExprClass:
10251 case Expr::BlockExprClass:
10253 case Expr::OpaqueValueExprClass:
10254 case Expr::PackExpansionExprClass:
10255 case Expr::SubstNonTypeTemplateParmPackExprClass:
10256 case Expr::FunctionParmPackExprClass:
10257 case Expr::AsTypeExprClass:
10258 case Expr::ObjCIndirectCopyRestoreExprClass:
10259 case Expr::MaterializeTemporaryExprClass:
10260 case Expr::PseudoObjectExprClass:
10261 case Expr::AtomicExprClass:
10262 case Expr::LambdaExprClass:
10263 case Expr::CXXFoldExprClass:
10264 case Expr::CoawaitExprClass:
10265 case Expr::DependentCoawaitExprClass:
10266 case Expr::CoyieldExprClass:
10269 case Expr::InitListExprClass: {
10275 if (cast<InitListExpr>(E)->getNumInits() == 1)
10276 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
10280 case Expr::SizeOfPackExprClass:
10281 case Expr::GNUNullExprClass:
10285 case Expr::SubstNonTypeTemplateParmExprClass:
10287 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
10289 case Expr::ParenExprClass:
10290 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
10291 case Expr::GenericSelectionExprClass:
10292 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
10293 case Expr::IntegerLiteralClass:
10294 case Expr::CharacterLiteralClass:
10295 case Expr::ObjCBoolLiteralExprClass:
10296 case Expr::CXXBoolLiteralExprClass:
10297 case Expr::CXXScalarValueInitExprClass:
10298 case Expr::TypeTraitExprClass:
10299 case Expr::ArrayTypeTraitExprClass:
10300 case Expr::ExpressionTraitExprClass:
10301 case Expr::CXXNoexceptExprClass:
10303 case Expr::CallExprClass:
10304 case Expr::CXXOperatorCallExprClass: {
10308 const CallExpr *CE = cast<CallExpr>(
E);
10313 case Expr::DeclRefExprClass: {
10314 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
10322 if (isa<ParmVarDecl>(D))
10323 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
10328 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
10329 if (!Dcl->getType()->isIntegralOrEnumerationType())
10330 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
10338 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
10343 case Expr::UnaryOperatorClass: {
10370 case Expr::OffsetOfExprClass: {
10379 case Expr::UnaryExprOrTypeTraitExprClass: {
10386 case Expr::BinaryOperatorClass: {
10430 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
10433 return ICEDiag(IK_ICEIfUnevaluated, E->
getLocStart());
10434 if (REval.isSigned() && REval.isAllOnesValue()) {
10436 if (LEval.isMinSignedValue())
10437 return ICEDiag(IK_ICEIfUnevaluated, E->
getLocStart());
10445 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
10446 return ICEDiag(IK_ICEIfUnevaluated, E->
getLocStart());
10452 return Worst(LHSResult, RHSResult);
10458 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
10468 return Worst(LHSResult, RHSResult);
10473 case Expr::ImplicitCastExprClass:
10474 case Expr::CStyleCastExprClass:
10475 case Expr::CXXFunctionalCastExprClass:
10476 case Expr::CXXStaticCastExprClass:
10477 case Expr::CXXReinterpretCastExprClass:
10478 case Expr::CXXConstCastExprClass:
10479 case Expr::ObjCBridgedCastExprClass: {
10480 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
10481 if (isa<ExplicitCastExpr>(E)) {
10486 APSInt IgnoredVal(DestWidth, !DestSigned);
10491 if (FL->getValue().convertToInteger(IgnoredVal,
10492 llvm::APFloat::rmTowardZero,
10493 &Ignored) & APFloat::opInvalidOp)
10498 switch (cast<CastExpr>(E)->getCastKind()) {
10499 case CK_LValueToRValue:
10500 case CK_AtomicToNonAtomic:
10501 case CK_NonAtomicToAtomic:
10503 case CK_IntegralToBoolean:
10504 case CK_IntegralCast:
10510 case Expr::BinaryConditionalOperatorClass: {
10513 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
10515 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
10516 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
10517 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
10519 return FalseResult;
10521 case Expr::ConditionalOperatorClass: {
10529 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
10532 if (CondResult.Kind == IK_NotICE)
10538 if (TrueResult.Kind == IK_NotICE)
10540 if (FalseResult.Kind == IK_NotICE)
10541 return FalseResult;
10542 if (CondResult.Kind == IK_ICEIfUnevaluated)
10544 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
10550 return FalseResult;
10553 case Expr::CXXDefaultArgExprClass:
10554 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
10555 case Expr::CXXDefaultInitExprClass:
10556 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
10557 case Expr::ChooseExprClass: {
10558 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
10562 llvm_unreachable(
"Invalid StmtClass!");
10568 llvm::APSInt *Value,
10579 if (!Result.
isInt()) {
10584 if (Value) *Value = Result.
getInt();
10594 if (D.Kind != IK_ICE) {
10595 if (Loc) *Loc = D.Loc;
10613 llvm_unreachable(
"ICE cannot be evaluated!");
10618 return CheckICE(
this, Ctx).Kind == IK_ICE;
10630 Status.Diag = &Diags;
10631 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
10636 if (!Diags.empty()) {
10637 IsConstExpr =
false;
10638 if (Loc) *Loc = Diags[0].first;
10639 }
else if (!IsConstExpr) {
10644 return IsConstExpr;
10650 const Expr *This)
const {
10652 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
10655 const LValue *ThisPtr =
nullptr;
10659 assert(MD &&
"Don't provide `this` for non-methods.");
10660 assert(!MD->isStatic() &&
"Don't provide `this` for static methods.");
10663 ThisPtr = &ThisVal;
10664 if (Info.EvalStatus.HasSideEffects)
10668 ArgVector ArgValues(Args.size());
10671 if ((*I)->isValueDependent() ||
10672 !
Evaluate(ArgValues[I - Args.begin()], Info, *
I))
10674 ArgValues[I - Args.begin()] =
APValue();
10675 if (Info.EvalStatus.HasSideEffects)
10680 CallStackFrame Frame(Info, Callee->
getLocation(), Callee, ThisPtr,
10682 return Evaluate(Value, Info,
this) && !Info.EvalStatus.HasSideEffects;
10695 Status.
Diag = &Diags;
10698 EvalInfo::EM_PotentialConstantExpression);
10707 This.set(&VIE, Info.CurrentCall->Index);
10715 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
10720 Args, FD->
getBody(), Info, Scratch,
nullptr);
10723 return Diags.empty();
10731 Status.
Diag = &Diags;
10734 EvalInfo::EM_PotentialConstantExpressionUnevaluated);
10738 ArgVector ArgValues(0);
10742 "Failed to set up arguments for potential constant evaluation");
10743 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
10747 return Diags.empty();
10751 unsigned Type)
const {
10752 if (!
getType()->isPointerType())
10756 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
unsigned getNumElements() const
unsigned getAddressSpace() const
Return the address space of this type.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, llvm::Type *BaseLVType, CharUnits BaseLVAlignment, llvm::Value *Addr)
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
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.
unsigned getNumInits() const
const SwitchCase * getNextSwitchCase() const
StmtClass getStmtClass() const
CastKind getCastKind() const
The null pointer literal (C++11 [lex.nullptr])
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Expr ** getArgs()
Retrieve the call arguments.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
bool isNullPtrType() const
const FieldDecl * getUnionField() const
static bool IsGlobalLValue(APValue::LValueBase B)
PointerType - C99 6.7.5.1 - Pointer Declarators.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
A (possibly-)qualified type.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool isBitField() const
Determines whether this field is a bitfield.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
bool isMemberPointerType() const
QualType getType() const
Retrieves the type of the base class.
bool isElidable() const
Whether this construction is elidable.
bool operator==(CanQual< T > x, CanQual< U > y)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
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()
Stmt - This represents one statement.
bool isArgumentType() const
IfStmt - This represents an if/then/else.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
unsigned getIntWidth(QualType T) const
SourceLocation getLocStart() const LLVM_READONLY
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
void addConst()
Add the const type qualifier to this QualType.
ActionResult< Expr * > ExprResult
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
TypeSourceInfo * getTypeSourceInfo() const
bool isRecordType() const
unsigned getPackLength() const
Retrieve the length of the parameter pack.
Decl - This represents one declaration (or definition), e.g.
capture_const_iterator captures_begin() const
__DEVICE__ long long abs(long long __n)
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 isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
bool isVoidPointerType() const
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
ParenExpr - This represents a parethesized expression, e.g.
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)
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
The base class of the type hierarchy.
bool isMemberPointer() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsConstNonVolatile(QualType T)
std::unique_ptr< llvm::MemoryBuffer > Buffer
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.
const Expr * getResultExpr() const
The generic selection's result expression.
const Expr * getInit() const
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
bool hasLValuePath() const
Represents a call to a C++ constructor.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
bool isBooleanType() 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...
llvm::DenseMap< Stmt *, Stmt * > MapTy
const Stmt * getElse() const
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
SourceLocation getLocEnd() const LLVM_READONLY
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.
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.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
const llvm::APInt & getSize() const
Expr * getIndexExpr(unsigned Idx)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D)
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)?
const CXXBaseSpecifier *const * path_const_iterator
This file provides some common utility functions for processing Lambda related AST Constructs...
VarDecl - An instance of this class is created to represent a variable declaration or definition...
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.
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getCallee() const
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
APFloat & getComplexFloatReal()
bool hasCaptures() const
hasCaptures - True if this block (or its nested blocks) captures anything of local storage from its e...
AccessSpecifier getAccess() const
field_iterator field_begin() const
The "__interface" keyword.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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 isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
UnaryExprOrTypeTrait getKind() const
bool isMemberDataPointerType() const
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
unsigned getValue() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
static bool isAssignmentOp(Opcode Opc)
ParmVarDecl - 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.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant...
unsigned path_size() const
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
The collection of all-type qualifiers we support.
static bool HasSameBase(const LValue &A, const LValue &B)
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
RecordDecl - Represents a struct/union/class.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
return(__x >> __y)|(__x<< (32-__y))
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size)
Get the size of the given type in char units.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
bool isComplexInt() const
bool isNullPointer() const
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
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)
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isReferenceType() const
QualType getReturnType() const
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 ...
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr...
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 getLValueCallIndex() const
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...
uint32_t getCodeUnit(size_t i) const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. ...
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.
static bool isEqualityOp(Opcode Opc)
const TargetInfo & getTargetInfo() const
static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, llvm::APInt &Res)
const LangOptions & getLangOpts() const
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)...
unsigned getLength() const
CharUnits - This is an opaque type for sizes expressed in character units.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
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.
static int EvaluateBuiltinClassifyType(const CallExpr *E, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
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...
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
bool isDefaulted() const
Whether this function is defaulted per C++0x.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Expr * getExprOperand() const
path_iterator path_begin()
field_range fields() const
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue...
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
static bool isRecordType(QualType T)
A builtin binary operation expression such as "x + y" or "x <= y".
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 isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
RecordDecl * getDecl() const
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
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.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr...
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...
TypeClass getTypeClass() const
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.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
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)
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
detail::InMemoryDirectory::const_iterator I
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 isUnnamedBitfield() const
Determines whether this is an unnamed bitfield.
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.
Represents the this expression in C++.
DiagnosticsEngine & getDiagnostics() const
field_iterator field_end() const
APValue & getVectorElt(unsigned I)
CXXConstructorDecl * getConstructor() const
bool isAddrLabelDiff() const
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
ConditionalOperator - The ?: ternary operator.
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type...
Expr * getFalseExpr() const
llvm::APInt getValue() const
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 }.
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
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.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
APValue & getArrayFiller()
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
const Expr * getExpr() const
Get the initialization expression that will be used.
bool HasUndefinedBehavior
Whether the evaluation hit undefined behavior.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isFunctionPointerType() const
bool hasUnaligned() const
bool isRealFloatingType() const
Floating point categories.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called...
unsigned getArrayInitializedElts() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
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 f...
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
bool isAnyComplexType() const
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "while" statement, if any.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
bool isMemberPointerToDerivedMember() const
ArrayRef< NamedDecl * > chain() const
bool isComplexFloat() const
bool isAtomicType() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
bool isVariableArrayType() const
const ParmVarDecl * getParamDecl(unsigned i) const
DeclContext * getDeclContext()
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
bool isFloatingType() 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)
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
Defines the clang::TypeLoc interface and its subclasses.
const SwitchCase * getSwitchCaseList() const
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
unsigned getConstexprBacktraceLimit() const
Retrieve the maximum number of constexpr evaluation notes to emit along with a given diagnostic...
static bool isOverflowingIntegerType(ASTContext &Ctx, QualType T)
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
static bool 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...
Expr * getSubExpr() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
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.
bool EvaluateAsInt(llvm::APSInt &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...
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?
unsigned getNumComponents() const
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
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.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
QualType getElementType() const
APSInt & getComplexIntImag()
QualType getComputationLHSType() const
bool isComplexIntegerType() const
The result type of a method or function.
static bool EvaluateArgs(ArrayRef< const Expr * > Args, ArgVector &ArgValues, EvalInfo &Info)
EvaluateArgs - Evaluate the arguments to a function call.
bool checkInitIsICE() const
Determine whether the value of the initializer attached to this declaration is an integral constant e...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
void EvaluateForOverflow(const ASTContext &Ctx) const
Expr * getTrueExpr() const
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).
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
const Expr * getAnyInitializer() const
getAnyInitializer - Get the initializer for this variable, no matter which declaration it is attached...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
DoStmt - This represents a 'do/while' stmt.
bool isLValueOnePastTheEnd() const
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...
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.
APValue & getStructBase(unsigned i)
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
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)
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const
EvaluateAsBooleanCondition - Return true if this is a constant which we we can fold and convert to a ...
APValue & getArrayInitializedElt(unsigned I)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Represents a call to an inherited base class constructor from an inheriting constructor.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
Encodes a location in the source.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getElementType() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this core constant expression value is a valid value for a constant expression.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
APValue & getUnionValue()
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6.7.5p3.
ASTContext & getASTContext() const LLVM_READONLY
bool isLocalVarDecl() const
isLocalVarDecl - Returns true for local variable declarations other than parameters.
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
ValueKind getKind() const
const Expr * getCond() const
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
static bool IsLiteralLValue(const LValue &Value)
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.
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...
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)
unsigned getCharByteWidth() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
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...
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "switch" statement, if any.
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
const T * castAs() const
Member-template castAs<specific type>.
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool isVectorType() const
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)
bool isMemberFunctionPointerType() const
uint64_t getValue() const
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E)
ObjCBoxedExpr - used for generalized expression boxing.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const BlockDecl * getBlockDecl() const
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
QualType getType() const
Return the type wrapped by this type source info.
bool isGlobalLValue() const
const OffsetOfNode & getComponent(unsigned Idx) const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isPtrMemOp() const
predicates to categorize the respective opcodes.
CompoundAssignOperator - For compound assignments (e.g.
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)
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
AddrLabelExpr - The GNU address of label extension, representing &&label.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
Expr * getReplacement() const
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "if" statement, if any.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class...
bool 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
[C99 6.4.2.2] - A predefined identifier such as func.
EvalResult is a struct with detailed info about an evaluated expression.
bool isZero() const
isZero - Test whether the quantity equals zero.
static bool isZeroSized(const LValue &Value)
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
const Stmt * getBody() const
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
bool isInvalidDecl() const
IndirectFieldDecl - An instance of this class is created to represent a field injected from an anonym...
A decomposition declaration.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
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...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
StringRef getString() const
SourceLocation getLocStart() const LLVM_READONLY
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
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...
unsigned getNumArgs() const
body_iterator body_begin()
Stmt *const * const_body_iterator
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).
llvm::APFloat getValue() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
const Stmt * getThen() const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
SwitchStmt - This represents a 'switch' stmt.
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...
ArrayRef< LValuePathEntry > getLValuePath() 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.
const T * getAs() const
Member-template getAs<specific type>'.
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
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 getCanonicalType() const
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
ObjCEncodeExpr, used for @encode in Objective-C.
static CharUnits GetAlignOfType(EvalInfo &Info, QualType T)
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
bool isFunctionType() const
static bool isAdditiveOp(Opcode Opc)
Expr * getArg(unsigned Arg)
Return the specified argument.
Base for LValueReferenceType and RValueReferenceType.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
ActionResult< Stmt * > StmtResult
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
const Expr * getSubExpr() const
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
SourceLocation getExprLoc() const LLVM_READONLY
LabelDecl * getLabel() const
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...
const Expr * getInitializer() const
unsigned getFieldIndex() const
getFieldIndex - Returns the index of this field within its record, as appropriate for passing to ASTR...
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
DeclStmt * getRangeStmt()
static bool isIncrementOp(Opcode Op)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condnition evaluates to false;...
A use of a default initializer in a constructor or in aggregate initialization.
A template argument list.
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
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 ...
const Expr * getSubExpr() const
bool hasArrayFiller() const
Return true if this is an array initializer and its array "filler" has been set.
APFloat & getComplexFloatImag()
const LValueBase getLValueBase() const
Represents a C++ struct/union/class.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
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...
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.
const Expr * getCond() const
base_class_iterator bases_end()
FieldDecl * getField() const
For a field offsetof node, returns the field.
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
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.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
capture_const_iterator captures_end() const
static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage...
bool isStringLiteralInit() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
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.
QualType getElementType() const
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
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.
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
const Expr * getInit(unsigned Init) const
static void expandStringLiteral(EvalInfo &Info, const Expr *Lit, APValue &Result)
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
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()
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
SourceLocation getLocation() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
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...
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
Automatic storage duration (most local variables).
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.
unsigned getArraySize() const
bool isConstQualified() const
Determine whether this type is const-qualified.
DeclStmt * getBeginStmt()
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 ...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
SourceLocation getLocStart() const LLVM_READONLY
static bool isComparisonOp(Opcode Opc)
Expr * getSubExpr() const
Get the initializer to use for each array element.
Represents the canonical version of C arrays with a specified constant size.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
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.
unsigned getVectorLength() const
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 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.
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
static void describeCall(CallStackFrame *Frame, raw_ostream &Out)
Produce a string describing the given constexpr call.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
Kind getKind() const
Determine what kind of offsetof node this is.
bool hasArrayFiller() const
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor...
const RecordDecl * getParent() const
getParent - Returns the parent of this field declaration, which is the struct in which this field is ...
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
CharUnits & getLValueOffset()
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isPointerType() const
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 getArgumentType() const