Skip to content

Commit cb70343

Browse files
committed
[clang][Interp] Add back Run() call
We need to run the functions we compiled immediately after to check if they can ever be a constant expression. Differential Revision: https://reviews.llvm.org/D140724
1 parent 8b70d97 commit cb70343

File tree

7 files changed

+41
-16
lines changed

7 files changed

+41
-16
lines changed

clang/lib/AST/Interp/Context.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) {
4242
}
4343
}
4444

45+
APValue DummyResult;
46+
if (!Run(Parent, Func, DummyResult)) {
47+
return false;
48+
}
49+
4550
return Func->isConstexpr();
4651
}
4752

clang/lib/AST/Interp/Interp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
342342
}
343343

344344
if (!F->isConstexpr()) {
345+
// Don't emit anything if we're checking for a potential constant
346+
// expression. That will happen later when actually executing.
347+
if (S.checkingPotentialConstantExpression())
348+
return false;
349+
345350
const SourceLocation &Loc = S.Current->getLocation(OpPC);
346351
if (S.getLangOpts().CPlusPlus11) {
347352
const FunctionDecl *DiagDecl = F->getDecl();

clang/lib/AST/Interp/Interp.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,8 @@ inline bool This(InterpState &S, CodePtr OpPC) {
13111311

13121312
inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
13131313
assert(S.Current->getFunction()->hasRVO());
1314+
if (S.checkingPotentialConstantExpression())
1315+
return false;
13141316
S.Stk.push<Pointer>(S.Current->getRVOPtr());
13151317
return true;
13161318
}
@@ -1383,9 +1385,11 @@ inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) {
13831385
Pointer ThisPtr;
13841386
if (Func->hasThisPointer()) {
13851387
ThisPtr = NewFrame->getThis();
1386-
if (!CheckInvoke(S, PC, ThisPtr)) {
1388+
if (!CheckInvoke(S, PC, ThisPtr))
1389+
return false;
1390+
1391+
if (S.checkingPotentialConstantExpression())
13871392
return false;
1388-
}
13891393
}
13901394

13911395
if (!CheckCallable(S, PC, Func))

clang/test/AST/Interp/arrays.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ class AU {
209209
public:
210210
int a;
211211
constexpr AU() : a(5 / 0) {} // expected-warning {{division by zero is undefined}} \
212-
// expected-note {{division by zero}} \
212+
// expected-note 2{{division by zero}} \
213+
// expected-error {{never produces a constant expression}} \
213214
// ref-error {{never produces a constant expression}} \
214215
// ref-note 2{{division by zero}} \
215216
// ref-warning {{division by zero is undefined}}
@@ -296,20 +297,22 @@ namespace IncDec {
296297
}
297298
static_assert(getSecondToLast2() == 3, "");
298299

299-
constexpr int bad1() { // ref-error {{never produces a constant expression}}
300+
constexpr int bad1() { // ref-error {{never produces a constant expression}} \
301+
// expected-error {{never produces a constant expression}}
300302
const int *e = E + 3;
301303
e++; // This is fine because it's a one-past-the-end pointer
302-
return *e; // expected-note {{read of dereferenced one-past-the-end pointer}} \
304+
return *e; // expected-note 2{{read of dereferenced one-past-the-end pointer}} \
303305
// ref-note 2{{read of dereferenced one-past-the-end pointer}}
304306
}
305307
static_assert(bad1() == 0, ""); // expected-error {{not an integral constant expression}} \
306308
// expected-note {{in call to}} \
307309
// ref-error {{not an integral constant expression}} \
308310
// ref-note {{in call to}}
309311

310-
constexpr int bad2() { // ref-error {{never produces a constant expression}}
312+
constexpr int bad2() { // ref-error {{never produces a constant expression}} \
313+
// expected-error {{never produces a constant expression}}
311314
const int *e = E + 4;
312-
e++; // expected-note {{cannot refer to element 5 of array of 4 elements}} \
315+
e++; // expected-note 2{{cannot refer to element 5 of array of 4 elements}} \
313316
// ref-note 2{{cannot refer to element 5 of array of 4 elements}}
314317
return *e; // This is UB as well
315318
}
@@ -319,9 +322,10 @@ namespace IncDec {
319322
// ref-note {{in call to}}
320323

321324

322-
constexpr int bad3() { // ref-error {{never produces a constant expression}}
325+
constexpr int bad3() { // ref-error {{never produces a constant expression}} \
326+
// expected-error {{never produces a constant expression}}
323327
const int *e = E;
324-
e--; // expected-note {{cannot refer to element -1 of array of 4 elements}} \
328+
e--; // expected-note 2{{cannot refer to element -1 of array of 4 elements}} \
325329
// ref-note 2{{cannot refer to element -1 of array of 4 elements}}
326330
return *e; // This is UB as well
327331
}

clang/test/AST/Interp/literals.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,11 @@ namespace IncDec {
452452
static_assert(uninit(), ""); // ref-error {{not an integral constant expression}} \
453453
// ref-note {{in call to 'uninit()'}}
454454

455-
constexpr int OverFlow() { // ref-error {{never produces a constant expression}}
455+
constexpr int OverFlow() { // ref-error {{never produces a constant expression}} \
456+
// expected-error {{never produces a constant expression}}
456457
int a = INT_MAX;
457458
++a; // ref-note 2{{is outside the range}} \
458-
// expected-note {{is outside the range}}
459+
// expected-note 2{{is outside the range}}
459460
return -1;
460461
}
461462
static_assert(OverFlow() == -1, ""); // expected-error {{not an integral constant expression}} \
@@ -464,10 +465,11 @@ namespace IncDec {
464465
// ref-note {{in call to 'OverFlow()'}}
465466

466467

467-
constexpr int UnderFlow() { // ref-error {{never produces a constant expression}}
468+
constexpr int UnderFlow() { // ref-error {{never produces a constant expression}} \
469+
// expected-error {{never produces a constant expression}}
468470
int a = INT_MIN;
469471
--a; // ref-note 2{{is outside the range}} \
470-
// expected-note {{is outside the range}}
472+
// expected-note 2{{is outside the range}}
471473
return -1;
472474
}
473475
static_assert(UnderFlow() == -1, ""); // expected-error {{not an integral constant expression}} \

clang/test/AST/Interp/records.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,11 @@ namespace thisPointer {
174174
constexpr int get12() { return 12; }
175175
};
176176

177-
constexpr int foo() { // ref-error {{never produces a constant expression}}
177+
constexpr int foo() { // ref-error {{never produces a constant expression}} \
178+
// expected-error {{never produces a constant expression}}
178179
S *s = nullptr;
179180
return s->get12(); // ref-note 2{{member call on dereferenced null pointer}} \
180-
// expected-note {{member call on dereferenced null pointer}}
181+
// expected-note 2{{member call on dereferenced null pointer}}
181182

182183
}
183184
static_assert(foo() == 12, ""); // ref-error {{not an integral constant expression}} \

clang/test/AST/Interp/shifts.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88

99
namespace shifts {
1010
constexpr void test() { // ref-error {{constexpr function never produces a constant expression}} \
11-
// ref-cxx17-error {{constexpr function never produces a constant expression}}
11+
// ref-cxx17-error {{constexpr function never produces a constant expression}} \
12+
// expected-error {{constexpr function never produces a constant expression}} \
13+
// cxx17-error {{constexpr function never produces a constant expression}} \
1214
1315
char c; // cxx17-warning {{uninitialized variable}} \
1416
// ref-cxx17-warning {{uninitialized variable}}
@@ -19,6 +21,8 @@ namespace shifts {
1921
c = 1 << -0;
2022
c = 1 >> -0;
2123
c = 1 << -1; // expected-warning {{shift count is negative}} \
24+
// expected-note {{negative shift count -1}} \
25+
// cxx17-note {{negative shift count -1}} \
2226
// cxx17-warning {{shift count is negative}} \
2327
// ref-warning {{shift count is negative}} \
2428
// ref-note {{negative shift count -1}} \

0 commit comments

Comments
 (0)