aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.h')
-rw-r--r--clang/lib/AST/ByteCode/Interp.h55
1 files changed, 27 insertions, 28 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 9012442..8a28106 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -25,7 +25,6 @@
#include "InterpStack.h"
#include "InterpState.h"
#include "MemberPointer.h"
-#include "Opcode.h"
#include "PrimType.h"
#include "Program.h"
#include "State.h"
@@ -92,8 +91,9 @@ bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
AccessKinds AK);
-/// Check if a global variable is initialized.
-bool CheckGlobalInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
+/// Checks a direct load of a primitive value from a global or local variable.
+bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
+bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
/// Checks if a value can be stored in a block.
bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
@@ -481,13 +481,11 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
Floating RA = S.allocFloat(A.getSemantics());
RA.copy(ResR);
Result.elem<Floating>(0) = RA; // Floating(ResR);
- Result.atIndex(0).initialize();
Floating RI = S.allocFloat(A.getSemantics());
RI.copy(ResI);
Result.elem<Floating>(1) = RI; // Floating(ResI);
- Result.atIndex(1).initialize();
- Result.initialize();
+ Result.initializeAllElements();
} else {
// Integer element type.
const T &LHSR = LHS.elem<T>(0);
@@ -505,7 +503,6 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
return false;
if (T::sub(A, B, Bits, &Result.elem<T>(0)))
return false;
- Result.atIndex(0).initialize();
// imag(Result) = (real(LHS) * imag(RHS)) + (imag(LHS) * real(RHS))
if (T::mul(LHSR, RHSI, Bits, &A))
@@ -514,8 +511,8 @@ inline bool Mulc(InterpState &S, CodePtr OpPC) {
return false;
if (T::add(A, B, Bits, &Result.elem<T>(1)))
return false;
- Result.atIndex(1).initialize();
Result.initialize();
+ Result.initializeAllElements();
}
return true;
@@ -541,14 +538,12 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
Floating RA = S.allocFloat(A.getSemantics());
RA.copy(ResR);
Result.elem<Floating>(0) = RA; // Floating(ResR);
- Result.atIndex(0).initialize();
Floating RI = S.allocFloat(A.getSemantics());
RI.copy(ResI);
Result.elem<Floating>(1) = RI; // Floating(ResI);
- Result.atIndex(1).initialize();
- Result.initialize();
+ Result.initializeAllElements();
} else {
// Integer element type.
const T &LHSR = LHS.elem<T>(0);
@@ -590,7 +585,6 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
return false;
if (T::div(ResultR, Den, Bits, &ResultR))
return false;
- Result.atIndex(0).initialize();
// imag(Result) = ((imag(LHS) * real(RHS)) - (real(LHS) * imag(RHS))) / Den
if (T::mul(LHSI, RHSR, Bits, &A) || T::mul(LHSR, RHSI, Bits, &B))
@@ -599,8 +593,7 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
return false;
if (T::div(ResultI, Den, Bits, &ResultI))
return false;
- Result.atIndex(1).initialize();
- Result.initialize();
+ Result.initializeAllElements();
}
return true;
@@ -1138,8 +1131,9 @@ inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_past_end)
<< LHS.toDiagnosticString(S.getASTContext());
return false;
- } else if (RHS.isOnePastEnd() && !LHS.isOnePastEnd() && !LHS.isZero() &&
- LHS.getOffset() == 0) {
+ }
+ if (RHS.isOnePastEnd() && !LHS.isOnePastEnd() && !LHS.isZero() &&
+ LHS.getOffset() == 0) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_past_end)
<< RHS.toDiagnosticString(S.getASTContext());
@@ -1157,8 +1151,9 @@ inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_literal_comparison);
return false;
- } else if (const auto *CE = dyn_cast<CallExpr>(E);
- CE && IsOpaqueConstantCall(CE)) {
+ }
+ if (const auto *CE = dyn_cast<CallExpr>(E);
+ CE && IsOpaqueConstantCall(CE)) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.FFDiag(Loc, diag::note_constexpr_opaque_call_comparison)
<< P.toDiagnosticString(S.getASTContext());
@@ -1357,7 +1352,7 @@ inline bool ConstFloat(InterpState &S, CodePtr OpPC, const Floating &F) {
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
const Pointer &Ptr = S.Current->getLocalPointer(I);
- if (!CheckLoad(S, OpPC, Ptr))
+ if (!CheckLocalLoad(S, OpPC, Ptr))
return false;
S.Stk.push<T>(Ptr.deref<T>());
return true;
@@ -1471,14 +1466,8 @@ bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
const Pointer &Ptr = S.P.getPtrGlobal(I);
- if (!CheckConstant(S, OpPC, Ptr.getFieldDesc()))
- return false;
- if (Ptr.isExtern())
- return false;
- // If a global variable is uninitialized, that means the initializer we've
- // compiled for it wasn't a constant expression. Diagnose that.
- if (!CheckGlobalInitialized(S, OpPC, Ptr))
+ if (!CheckGlobalLoad(S, OpPC, Ptr))
return false;
S.Stk.push<T>(Ptr.deref<T>());
@@ -2688,6 +2677,14 @@ static inline bool CastFixedPointIntegral(InterpState &S, CodePtr OpPC) {
return true;
}
+static inline bool FnPtrCast(InterpState &S, CodePtr OpPC) {
+ const SourceInfo &E = S.Current->getSource(OpPC);
+ S.CCEDiag(E, diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
+ << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
+ return true;
+}
+
static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
const auto &Ptr = S.Stk.peek<Pointer>();
@@ -3273,7 +3270,8 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
<< static_cast<unsigned>(Kind) << S.Current->getRange(OpPC);
return !Fatal;
- } else if (Kind == CastKind::Volatile) {
+ }
+ if (Kind == CastKind::Volatile) {
if (!S.checkingPotentialConstantExpression()) {
const auto *E = cast<CastExpr>(S.Current->getExpr(OpPC));
if (S.getLangOpts().CPlusPlus)
@@ -3284,7 +3282,8 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
}
return false;
- } else if (Kind == CastKind::Dynamic) {
+ }
+ if (Kind == CastKind::Dynamic) {
assert(!S.getLangOpts().CPlusPlus20);
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
<< diag::ConstexprInvalidCastKind::Dynamic;