Go to the documentation of this file.
24 #include "llvm/ADT/APSInt.h"
26 using namespace clang;
33 template <PrimType Name, class T = typename PrimConv<Name>::T>
36 const T &
Ret = S.Stk.pop<T>();
38 assert(S.Current->getFrameOffset() == S.Stk.size() &&
"Invalid frame");
39 if (!S.checkingPotentialConstantExpression())
43 PC = S.Current->getRetPC();
50 if (!ReturnValue<T>(
Ret, Result))
59 assert(S.Current->getFrameOffset() == S.Stk.size() &&
"Invalid frame");
60 if (!S.checkingPotentialConstantExpression())
64 PC = S.Current->getRetPC();
75 llvm::report_fatal_error(
"Interpreter cannot return values");
88 if (S.Stk.pop<
bool>()) {
95 if (!S.Stk.pop<
bool>()) {
105 if (!S.checkingPotentialConstantExpression()) {
106 const SourceInfo &Loc = S.Current->getSource(OpPC);
107 S.FFDiag(Loc, diag::note_constexpr_access_uninit) << AK <<
false;
122 while (!
U.isActive()) {
128 assert(R && R->
isUnion() &&
"Not a union");
130 for (
unsigned I = 0, N = R->
getNumFields(); I < N; ++I) {
132 if (Field.isActive()) {
133 ActiveField = Field.getField();
138 const SourceInfo &Loc = S.Current->getSource(OpPC);
139 S.FFDiag(Loc, diag::note_constexpr_access_inactive_union_member)
140 << AK << InactiveField << !ActiveField << ActiveField;
153 if (S.P.getCurrentDecl() ==
ID)
156 const SourceInfo &E = S.Current->getSource(OpPC);
157 S.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
158 S.Note(Ptr.
getDeclLoc(), diag::note_constexpr_temporary_here);
169 if (S.P.getCurrentDecl() ==
ID)
172 S.FFDiag(S.Current->getLocation(OpPC), diag::note_constexpr_modify_global);
185 if (!S.checkingPotentialConstantExpression()) {
187 const SourceInfo &Loc = S.Current->getSource(OpPC);
188 S.FFDiag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
189 S.Note(VD->getLocation(), diag::note_declared_at);
197 const SourceInfo &E = S.Current->getSource(OpPC);
198 S.FFDiag(E, diag::note_constexpr_unsized_array_indexed);
204 const auto &Src = S.Current->getSource(OpPC);
208 S.FFDiag(Src, diag::note_constexpr_null_subobject) <<
CSK_Field;
210 S.FFDiag(Src, diag::note_constexpr_access_null) << AK;
218 S.FFDiag(Src, diag::note_constexpr_lifetime_ended, 1) << AK << !IsTemp;
221 S.Note(Ptr.
getDeclLoc(), diag::note_constexpr_temporary_here);
223 S.Note(Ptr.
getDeclLoc(), diag::note_declared_at);
235 const SourceInfo &Loc = S.Current->getSource(OpPC);
236 S.FFDiag(Loc, diag::note_constexpr_null_subobject) << CSK;
244 const SourceInfo &Loc = S.Current->getSource(OpPC);
245 S.FFDiag(Loc, diag::note_constexpr_access_past_end) << AK;
253 const SourceInfo &Loc = S.Current->getSource(OpPC);
254 S.FFDiag(Loc, diag::note_constexpr_past_end_subobject) << CSK;
259 assert(Ptr.
isLive() &&
"Pointer is not live");
265 const SourceInfo &Loc = S.Current->getSource(OpPC);
266 S.FFDiag(Loc, diag::note_constexpr_modify_const_type) << Ty;
271 assert(Ptr.
isLive() &&
"Pointer is not live");
276 const SourceInfo &Loc = S.Current->getSource(OpPC);
278 S.FFDiag(Loc, diag::note_constexpr_access_mutable, 1) <<
AK_Read << Field;
279 S.Note(Field->getLocation(), diag::note_declared_at);
338 S.CCEDiag(Loc, diag::note_constexpr_virtual_call);
349 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
350 if (CD && CD->isInheritingConstructor()) {
351 auto *Inherited = CD->getInheritedConstructor().getConstructor();
352 if (!Inherited->isConstexpr())
353 DiagDecl = CD = Inherited;
359 if (CD && CD->isInheritingConstructor())
360 S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1)
361 << CD->getInheritedConstructor().getConstructor()->getParent();
363 S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1)
365 S.Note(DiagDecl->
getLocation(), diag::note_declared_at);
367 S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
379 const SourceInfo &Loc = S.Current->getSource(OpPC);
381 bool IsImplicit =
false;
382 if (
auto *E = dyn_cast_or_null<CXXThisExpr>(Loc.
asExpr()))
383 IsImplicit = E->isImplicit();
386 S.FFDiag(Loc, diag::note_constexpr_this) << IsImplicit;
396 const SourceInfo &E = S.Current->getSource(OpPC);
397 S.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << MD;
402 CodePtr PC = S.Current->getPC();
410 #include "Opcodes.inc"
bool isUnion() const
Checks if the record is a union.
const Expr * asExpr() const
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
bool CheckCallable(InterpState &S, CodePtr OpPC, Function *F)
Checks if a method can be called.
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This)
Checks the 'this' pointer.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
static bool CheckGlobal(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Encodes a location in the source.
A (possibly-)qualified type.
bool isMutable() const
Checks if the field is mutable.
Represents a member of a struct/union/class.
static bool Jt(InterpState &S, CodePtr &PC, int32_t Offset)
const Field * getField(const FieldDecl *FD) const
Returns a field.
SourceLocation getDeclLoc() const
Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
static bool RetValue(InterpState &S, CodePtr &Pt, APValue &Result)
bool isField() const
Checks if the item is a field in an object.
bool isConstexpr() const
Checks if the function is valid to call in constexpr.
static bool Jmp(InterpState &S, CodePtr &PC, int32_t Offset)
bool isTemporary() const
Checks if the storage is temporary.
A pointer to a memory block, live or dead.
bool CheckInvoke(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a method can be invoked on an object.
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
const LangOptions & getLangOpts() const
Frame storing local variables.
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
bool isStaticTemporary() const
Checks if the storage is a static temporary.
bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the variable has externally defined storage.
bool isElementPastEnd() const
Checks if the pointer is an out-of-bounds element pointer.
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a value can be loaded from a block.
bool isLive() const
Checks if the pointer is live.
bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a value can be stored in a block.
bool isConst() const
Checks if an object or a subfield is mutable.
static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
Describes the statement/declaration an opcode was generated from.
QualType getType() const
Returns the type of the innermost field.
bool Interpret(InterpState &S, APValue &Result)
Interpreter entry point.
bool CheckPure(InterpState &S, CodePtr OpPC, const CXXMethodDecl *MD)
Checks if a method is pure virtual.
static bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result)
const ValueDecl * asValueDecl() const
bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer points to a mutable field.
std::enable_if_t<!std::is_pointer< T >::value, T > read()
Reads data and advances the pointer.
bool isPure() const
Whether this virtual function is pure, i.e.
bool isZero() const
Checks if the pointer is null.
Pointer into the code segment.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
bool isInitialized() const
Checks if an object was initialized.
bool This(InterpState &S, CodePtr OpPC)
bool isActive() const
Checks if the object is active.
Pointer getBase() const
Returns a pointer to the object of which this pointer is a field.
bool isExtern() const
Checks if the storage is extern.
bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer points to const storage.
const FieldDecl * getField() const
Returns the field information.
bool isStatic() const
Checks if the storage is static.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool isVirtual() const
Checks if the function is virtual.
llvm::Optional< unsigned > getDeclID() const
Returns the declaration ID.
static bool Jf(InterpState &S, CodePtr &PC, int32_t Offset)
bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a value can be initialized.
bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr, CheckSubobjectKind CSK)
Checks if a pointer is null.
Structure/Class descriptor.
SourceLocation getLocation() const
static bool CheckTemporary(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Represents a function declaration or definition.
bool isUnknownSizeArray() const
Checks if the structure is an array of unknown size.
static bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Represents a static or instance method of a struct/union/class.
bool isOnePastEnd() const
Checks if the index is one past end.