[clang][bytecode] Allow This pointers in CPCE mode (#137761)
The outermost function doesn't have a This pointers, but inner calls
can. This still doesn't match the diagnostic output of the current
interpreter properly, but it's closer I think.
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 80488b5..c89e68a 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1517,7 +1517,7 @@
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool InitThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
- if (S.checkingPotentialConstantExpression())
+ if (S.checkingPotentialConstantExpression() && S.Current->getDepth() == 0)
return false;
const Pointer &This = S.Current->getThis();
if (!CheckThis(S, OpPC, This))
@@ -1535,7 +1535,7 @@
bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F,
uint32_t FieldOffset) {
assert(F->isBitField());
- if (S.checkingPotentialConstantExpression())
+ if (S.checkingPotentialConstantExpression() && S.Current->getDepth() == 0)
return false;
const Pointer &This = S.Current->getThis();
if (!CheckThis(S, OpPC, This))
@@ -1602,7 +1602,7 @@
bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off);
inline bool GetPtrThisField(InterpState &S, CodePtr OpPC, uint32_t Off) {
- if (S.checkingPotentialConstantExpression())
+ if (S.checkingPotentialConstantExpression() && S.Current->getDepth() == 0)
return false;
const Pointer &This = S.Current->getThis();
if (!CheckThis(S, OpPC, This))
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index f879360..46f9e48 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -48,10 +48,10 @@
constexpr NonTrivial(const NonTrivial &) : n(1) {}
int n;
};
- constexpr bool test_nontrivial_memcpy() { // ref-error {{never produces a constant}}
+ constexpr bool test_nontrivial_memcpy() { // both-error {{never produces a constant}}
NonTrivial arr[3] = {};
__builtin_memcpy(arr, arr + 1, sizeof(NonTrivial)); // both-note {{non-trivially-copyable}} \
- // ref-note {{non-trivially-copyable}}
+ // both-note {{non-trivially-copyable}}
return true;
}
static_assert(test_nontrivial_memcpy()); // both-error {{constant}} \
diff --git a/clang/test/AST/ByteCode/unions.cpp b/clang/test/AST/ByteCode/unions.cpp
index 3911a2b2..36f4b72 100644
--- a/clang/test/AST/ByteCode/unions.cpp
+++ b/clang/test/AST/ByteCode/unions.cpp
@@ -76,9 +76,10 @@
constexpr U1 u1; /// OK.
- constexpr int foo() {
+ constexpr int foo() { // expected-error {{never produces a constant expression}}
U1 u;
- return u.a; // both-note {{read of member 'a' of union with active member 'b'}}
+ return u.a; // both-note {{read of member 'a' of union with active member 'b'}} \
+ // expected-note {{read of member 'a' of union with active member 'b'}}
}
static_assert(foo() == 42); // both-error {{not an integral constant expression}} \
// both-note {{in call to}}