clang 22.0.0git
InterpHelpers.h
Go to the documentation of this file.
1//===--- InterpHelpers.h - Interpreter Helper Functions --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_AST_INTERP_INTERPHELPERS_H
10#define LLVM_CLANG_AST_INTERP_INTERPHELPERS_H
11
12#include "DynamicAllocator.h"
13#include "InterpState.h"
14#include "Pointer.h"
15
16namespace clang {
17class CallExpr;
18class OffsetOfExpr;
19
20namespace interp {
21class Block;
22struct Descriptor;
23
24/// Interpreter entry point.
25bool Interpret(InterpState &S);
26
27/// Interpret a builtin function.
28bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
29 uint32_t BuiltinID);
30
31/// Interpret an offsetof operation.
32bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
33 ArrayRef<int64_t> ArrayIndices, int64_t &Result);
34
35/// Checks if the array is offsetable.
36bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
37
38/// Checks if a pointer is live and accessible.
39bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
40 AccessKinds AK);
41
42/// Checks if a pointer is a dummy pointer.
43bool CheckDummy(InterpState &S, CodePtr OpPC, const Block *B, AccessKinds AK);
44
45/// Checks if a pointer is in range.
46bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
47 AccessKinds AK);
48
49/// Checks if a field from which a pointer is going to be derived is valid.
50bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
52
53/// Checks if a pointer points to a mutable field.
54bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
55
56/// Checks if a value can be loaded from a block.
57bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
58 AccessKinds AK = AK_Read);
59
60/// Diagnose mismatched new[]/delete or new/delete[] pairs.
62 DynamicAllocator::Form AllocForm,
63 DynamicAllocator::Form DeleteForm, const Descriptor *D,
64 const Expr *NewExpr);
65
66/// Copy the contents of Src into Dest.
67bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest);
68
69template <typename T>
70static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue) {
71 const Expr *E = S.Current->getExpr(OpPC);
72 S.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << E->getType();
73 return S.noteUndefinedBehavior();
74}
75
76inline bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems) {
77 uint64_t Limit = S.getLangOpts().ConstexprStepLimit;
78 if (Limit != 0 && NumElems > Limit) {
79 S.FFDiag(S.Current->getSource(OpPC),
80 diag::note_constexpr_new_exceeds_limits)
81 << NumElems << Limit;
82 return false;
83 }
84 return true;
85}
86
87static inline llvm::RoundingMode getRoundingMode(FPOptions FPO) {
88 auto RM = FPO.getRoundingMode();
89 if (RM == llvm::RoundingMode::Dynamic)
90 return llvm::RoundingMode::NearestTiesToEven;
91 return RM;
92}
93
94inline bool Invalid(InterpState &S, CodePtr OpPC) {
95 const SourceLocation &Loc = S.Current->getLocation(OpPC);
96 S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr)
97 << S.Current->getRange(OpPC);
98 return false;
99}
100
101template <typename SizeT>
102bool CheckArraySize(InterpState &S, CodePtr OpPC, SizeT *NumElements,
103 unsigned ElemSize, bool IsNoThrow) {
104 // FIXME: Both the SizeT::from() as well as the
105 // NumElements.toAPSInt() in this function are rather expensive.
106
107 // Can't be too many elements if the bitwidth of NumElements is lower than
108 // that of Descriptor::MaxArrayElemBytes.
109 if ((NumElements->bitWidth() - NumElements->isSigned()) <
110 (sizeof(Descriptor::MaxArrayElemBytes) * 8))
111 return true;
112
113 // FIXME: GH63562
114 // APValue stores array extents as unsigned,
115 // so anything that is greater that unsigned would overflow when
116 // constructing the array, we catch this here.
117 SizeT MaxElements = SizeT::from(Descriptor::MaxArrayElemBytes / ElemSize);
118 assert(MaxElements.isPositive());
119 if (NumElements->toAPSInt().getActiveBits() >
121 *NumElements > MaxElements) {
122 if (!IsNoThrow) {
123 const SourceInfo &Loc = S.Current->getSource(OpPC);
124
125 if (NumElements->isSigned() && NumElements->isNegative()) {
126 S.FFDiag(Loc, diag::note_constexpr_new_negative)
127 << NumElements->toDiagnosticString(S.getASTContext());
128 } else {
129 S.FFDiag(Loc, diag::note_constexpr_new_too_large)
130 << NumElements->toDiagnosticString(S.getASTContext());
131 }
132 }
133 return false;
134 }
135 return true;
136}
137
138} // namespace interp
139} // namespace clang
140
141#endif // LLVM_CLANG_AST_INTERP_INTERPHELPERS_H
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2877
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
Definition Type.cpp:254
This represents one expression.
Definition Expr.h:112
QualType getType() const
Definition Expr.h:144
RoundingMode getRoundingMode() const
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2527
Encodes a location in the source.
A memory block, either on the stack or in the heap.
Definition InterpBlock.h:44
Pointer into the code segment.
Definition Source.h:30
const Expr * getExpr(CodePtr PC) const
SourceInfo getSource(CodePtr PC) const
Map a location to a source.
SourceLocation getLocation(CodePtr PC) const
SourceRange getRange(CodePtr PC) const
Interpreter context.
Definition InterpState.h:43
bool noteUndefinedBehavior() override
Definition InterpState.h:82
ASTContext & getASTContext() const override
Definition InterpState.h:70
InterpFrame * Current
The current frame.
const LangOptions & getLangOpts() const
Definition InterpState.h:71
A pointer to a memory block, live or dead.
Definition Pointer.h:91
Describes the statement/declaration an opcode was generated from.
Definition Source.h:73
OptionalDiagnostic FFDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation could not be folded (FF => FoldFailure)
Definition State.cpp:21
OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation does not produce a C++11 core constant expression.
Definition State.cpp:42
bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, DynamicAllocator::Form AllocForm, DynamicAllocator::Form DeleteForm, const Descriptor *D, const Expr *NewExpr)
Diagnose mismatched new[]/delete or new/delete[] pairs.
Definition Interp.cpp:1105
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
Definition Interp.cpp:1552
bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer points to a mutable field.
Definition Interp.cpp:594
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a value can be loaded from a block.
Definition Interp.cpp:793
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, ArrayRef< int64_t > ArrayIndices, int64_t &IntResult)
Interpret an offsetof operation.
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
Definition Interp.cpp:519
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
Definition Interp.cpp:414
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue)
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, uint32_t BuiltinID)
Interpret a builtin function.
bool CheckDummy(InterpState &S, CodePtr OpPC, const Block *B, AccessKinds AK)
Checks if a pointer is a dummy pointer.
Definition Interp.cpp:1156
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
Definition Interp.cpp:406
bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems)
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
bool Interpret(InterpState &S)
Interpreter entry point.
Definition Interp.cpp:2291
The JSON file list parser is used to communicate input to InstallAPI.
CheckSubobjectKind
The order of this enum is important for diagnostics.
Definition State.h:42
@ Result
The result type of a method or function.
Definition TypeBase.h:905
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
Definition State.h:26
@ AK_Read
Definition State.h:27
const FunctionProtoType * T
Describes a memory block created by an allocation site.
Definition Descriptor.h:122
static constexpr unsigned MaxArrayElemBytes
Maximum number of bytes to be used for array elements.
Definition Descriptor.h:148