summaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp17
-rw-r--r--clang/lib/AST/ByteCode/Interp.h25
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp12
-rw-r--r--clang/lib/AST/ByteCode/Opcodes.td2
-rw-r--r--clang/lib/AST/ByteCode/Pointer.cpp2
5 files changed, 45 insertions, 13 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 672fa7fc25d6..b960954d4754 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5738,9 +5738,17 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
// We should already have a pointer when we get here.
return this->delegate(SubExpr);
case UO_Deref: // *x
- if (DiscardResult)
+ if (DiscardResult) {
+ // assert(false);
return this->discard(SubExpr);
- return this->visit(SubExpr);
+ }
+
+ if (!this->visit(SubExpr))
+ return false;
+ if (classifyPrim(SubExpr) == PT_Ptr)
+ return this->emitNarrowPtr(E);
+ return true;
+
case UO_Not: // ~x
if (!T)
return this->emitError(E);
@@ -6089,7 +6097,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
if (VD->evaluateValue())
return revisit(VD);
- return this->emitInvalidDeclRef(cast<DeclRefExpr>(E), E);
+ return this->emitInvalidDeclRef(cast<DeclRefExpr>(E),
+ /*InitializerFailed=*/true, E);
}
}
} else {
@@ -6115,7 +6124,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
}
if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
- return this->emitInvalidDeclRef(DRE, E);
+ return this->emitInvalidDeclRef(DRE, /*InitializerFailed=*/false, E);
return false;
}
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index aafc848a9c53..c95b18ef72c9 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1944,14 +1944,14 @@ inline bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC) {
template <class T, ArithOp Op>
bool OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset,
- const Pointer &Ptr) {
+ const Pointer &Ptr, bool IsPointerArith = false) {
// A zero offset does not change the pointer.
if (Offset.isZero()) {
S.Stk.push<Pointer>(Ptr);
return true;
}
- if (!CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) {
+ if (IsPointerArith && !CheckNull(S, OpPC, Ptr, CSK_ArrayIndex)) {
// The CheckNull will have emitted a note already, but we only
// abort in C++, since this is fine in C.
if (S.getLangOpts().CPlusPlus)
@@ -2063,14 +2063,16 @@ bool AddOffset(InterpState &S, CodePtr OpPC) {
Pointer Ptr = S.Stk.pop<Pointer>();
if (Ptr.isBlockPointer())
Ptr = Ptr.expand();
- return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr);
+ return OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr,
+ /*IsPointerArith=*/true);
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool SubOffset(InterpState &S, CodePtr OpPC) {
const T &Offset = S.Stk.pop<T>();
const Pointer &Ptr = S.Stk.pop<Pointer>();
- return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr);
+ return OffsetHelper<T, ArithOp::Sub>(S, OpPC, Offset, Ptr,
+ /*IsPointerArith=*/true);
}
template <ArithOp Op>
@@ -2090,7 +2092,7 @@ static inline bool IncDecPtrHelper(InterpState &S, CodePtr OpPC,
// Now the current Ptr again and a constant 1.
OneT One = OneT::from(1);
- if (!OffsetHelper<OneT, Op>(S, OpPC, One, P))
+ if (!OffsetHelper<OneT, Op>(S, OpPC, One, P, /*IsPointerArith=*/true))
return false;
// Store the new value.
@@ -2816,9 +2818,18 @@ inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
return false;
}
-inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC,
- const DeclRefExpr *DR) {
+inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
+ bool InitializerFailed) {
assert(DR);
+
+ if (InitializerFailed) {
+ const SourceInfo &Loc = S.Current->getSource(OpPC);
+ const auto *VD = cast<VarDecl>(DR->getDecl());
+ S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
+ S.Note(VD->getLocation(), diag::note_declared_at);
+ return false;
+ }
+
return CheckDeclRef(S, OpPC, DR);
}
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index d4a8e6c2035e..10e33c14f4b4 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1253,6 +1253,10 @@ static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func,
const CallExpr *Call) {
+ if (!Call->getArg(0)->getType()->isIntegerType() ||
+ !Call->getArg(1)->getType()->isIntegerType())
+ return false;
+
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
PrimType IndexT = *S.Ctx.classify(Call->getArg(1));
APSInt Val = peekToAPSInt(S.Stk, ValT,
@@ -1331,6 +1335,10 @@ static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func,
const CallExpr *Call) {
+ if (!Call->getArg(0)->getType()->isIntegerType() ||
+ !Call->getArg(1)->getType()->isIntegerType())
+ return false;
+
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
PrimType MaskT = *S.Ctx.classify(Call->getArg(1));
@@ -1352,6 +1360,10 @@ static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func,
const CallExpr *Call) {
+ if (!Call->getArg(0)->getType()->isIntegerType() ||
+ !Call->getArg(1)->getType()->isIntegerType())
+ return false;
+
PrimType ValT = *S.Ctx.classify(Call->getArg(0));
PrimType MaskT = *S.Ctx.classify(Call->getArg(1));
diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td
index a1970f25ca97..9136e6b51660 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -769,7 +769,7 @@ def InvalidCast : Opcode {
}
def InvalidDeclRef : Opcode {
- let Args = [ArgDeclRef];
+ let Args = [ArgDeclRef, ArgBool];
}
def SizelessVectorElementSize : Opcode;
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 75b00dcb2ab2..c9de039c195d 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -635,7 +635,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
// Return the composite type.
APValue Result;
- if (!Composite(getType(), *this, Result))
+ if (!Composite(ResultType, *this, Result))
return std::nullopt;
return Result;
}