13#include "llvm/ADT/SetVector.h"
23 if (
const auto *
P = std::get_if<Pointer>(&
Value))
25 else if (
const auto *FP = std::get_if<FunctionPointer>(&
Value))
28 llvm_unreachable(
"Unhandled LValue type");
31 return std::get<APValue>(
Value);
35 llvm_unreachable(
"Unhandled result kind?");
46 if (
const auto *
P = std::get_if<Pointer>(&
Value))
48 else if (
const auto *FP = std::get_if<FunctionPointer>(&
Value))
50 llvm_unreachable(
"Unhandled lvalue kind");
55 assert(SubObjDecl &&
"Subobject declaration does not exist");
56 S.FFDiag(
Loc, diag::note_constexpr_uninitialized)
59 diag::note_constexpr_subobject_declared_here);
63 const Pointer &BasePtr,
const Record *R);
74 for (
size_t I = 0; I != NumElems; ++I) {
78 }
else if (
const auto *ElemCAT = dyn_cast<ConstantArrayType>(ElemType)) {
79 for (
size_t I = 0; I != NumElems; ++I) {
84 for (
size_t I = 0; I != NumElems; ++I) {
100 for (
const Record::Field &F : R->
fields()) {
102 QualType FieldType = F.Decl->getType();
112 }
else if (F.Decl->isUnnamedBitField()) {
125 for (
const Record::Base &B : R->
bases()) {
127 if (!
P.isInitialized()) {
131 diag::note_constexpr_uninitialized_base)
132 << B.Desc->getType();
135 diag::note_constexpr_uninitialized_base)
136 << B.Desc->getType();
162 if (
const auto *
D = Source.dyn_cast<
const Decl *>())
163 InitLoc = cast<VarDecl>(
D)->getAnyInitializer()->getExprLoc();
164 else if (
const auto *
E = Source.dyn_cast<
const Expr *>())
165 InitLoc =
E->getExprLoc();
170 if (
const auto *CAT = dyn_cast_if_present<ConstantArrayType>(
178 llvm::SetVector<const Block *> &Blocks) {
179 auto isUsefulPtr = [](
const Pointer &
P) ->
bool {
180 return P.isLive() && !
P.isZero() && !
P.isDummy() &&
181 !
P.isUnknownSizeArray() && !
P.isOnePastEnd() &&
P.isBlockPointer();
184 if (!isUsefulPtr(Ptr))
187 Blocks.insert(Ptr.
block());
194 for (
const Record::Field &F : R->fields()) {
201 if (isUsefulPtr(Pointee) && !Blocks.contains(Pointee.
block()))
205 for (
unsigned I = 0; I != Desc->
getNumElems(); ++I) {
207 if (isUsefulPtr(ElemPointee) && !Blocks.contains(ElemPointee.
block()))
211 for (
unsigned I = 0; I != Desc->
getNumElems(); ++I) {
223 llvm::SetVector<const Block *> Blocks;
227 for (
const Block *B : Blocks) {
228 if (B->isDynamic()) {
229 assert(B->getDescriptor());
230 assert(B->getDescriptor()->asExpr());
232 S.FFDiag(Info, diag::note_constexpr_dynamic_alloc)
234 S.Note(B->getDescriptor()->asExpr()->getExprLoc(),
235 diag::note_constexpr_dynamic_alloc_here);
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::MachO::Record Record
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
QualType getElementType() const
Represents the canonical version of C arrays with a specified constant size.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
A (possibly-)qualified type.
Encodes a location in the source.
bool isIncompleteArrayType() const
bool isReferenceType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isRecordType() const
A memory block, either on the stack or in the heap.
Holds all information required to evaluate constexpr code in a module.
ASTContext & getASTContext() const
Returns the AST context.
std::optional< APValue > toRValue() const
If the result is an LValue, convert that to an RValue and return it.
APValue toAPValue() const
Returns an APValue for the evaluation result.
QualType getSourceType() const
bool checkReturnValue(InterpState &S, const Context &Ctx, const Pointer &Ptr, const SourceInfo &Info)
Check that none of the blocks the given pointer (transitively) points to are dynamically allocated.
bool checkFullyInitialized(InterpState &S, const Pointer &Ptr) const
Check that all subobjects of the given pointer have been initialized.
A pointer to a memory block, live or dead.
Pointer narrow() const
Restricts the scope of an array element pointer.
bool isInitialized() const
Checks if an object was initialized.
Pointer atIndex(uint64_t Idx) const
Offsets a pointer inside an array.
bool isActive() const
Checks if the object is active.
Pointer atField(unsigned Off) const
Creates a pointer to a field.
T & deref() const
Dereferences the pointer, if it's live.
QualType getType() const
Returns the type of the innermost field.
bool isLive() const
Checks if the pointer is live.
bool isZero() const
Checks if the pointer is null.
bool isRoot() const
Pointer points directly to a block.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
const Record * getElemRecord() const
Returns the element record type, if this is a non-primive array.
const FieldDecl * getField() const
Returns the field information.
const Block * block() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
const Record * getRecord() const
Returns the record descriptor of a class.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
llvm::iterator_range< const_base_iter > bases() const
llvm::iterator_range< const_field_iter > fields() const
Describes the statement/declaration an opcode was generated from.
static void collectBlocks(const Pointer &Ptr, llvm::SetVector< const Block * > &Blocks)
static bool CheckFieldsInitialized(InterpState &S, SourceLocation Loc, const Pointer &BasePtr, const Record *R)
static void DiagnoseUninitializedSubobject(InterpState &S, SourceLocation Loc, const FieldDecl *SubObjDecl)
static bool CheckArrayInitialized(InterpState &S, SourceLocation Loc, const Pointer &BasePtr, const ConstantArrayType *CAT)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
const Decl * asDecl() const
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
const Record *const ElemRecord
Pointer to the record, if block contains records.
const Expr * asExpr() const