Skip to content

Commit 6a8ab12

Browse files
committed
[clang][Interp] Properly emit call ops to invalid functions
Just like everywhere else, we can't just abort compilation because a function is invalid. We need to emit the Call op and let later interpretation handle the failure. This fixes a long standing FIXME comment.
1 parent a1155f6 commit 6a8ab12

File tree

4 files changed

+8
-14
lines changed

4 files changed

+8
-14
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2835,14 +2835,6 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
28352835
const Function *Func = getFunction(FuncDecl);
28362836
if (!Func)
28372837
return false;
2838-
// If the function is being compiled right now, this is a recursive call.
2839-
// In that case, the function can't be valid yet, even though it will be
2840-
// later.
2841-
// If the function is already fully compiled but not constexpr, it was
2842-
// found to be faulty earlier on, so bail out.
2843-
if (Func->isFullyCompiled() && !Func->isConstexpr())
2844-
return false;
2845-
28462838
assert(HasRVO == Func->hasRVO());
28472839

28482840
bool HasQualifier = false;

clang/lib/AST/Interp/Interp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,11 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
477477
if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression())
478478
return false;
479479

480+
// If the declaration is defined _and_ declared 'constexpr', the below
481+
// diagnostic doesn't add anything useful.
482+
if (DiagDecl->isDefined() && DiagDecl->isConstexpr())
483+
return false;
484+
480485
S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1)
481486
<< DiagDecl->isConstexpr() << (bool)CD << DiagDecl;
482487
S.Note(DiagDecl->getLocation(), diag::note_declared_at);

clang/test/AST/Interp/cxx20.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,15 +230,13 @@ namespace ConstThis {
230230
// ref-note {{declared const here}}
231231
int a;
232232
public:
233-
constexpr Foo() { // expected-note {{declared here}}
233+
constexpr Foo() {
234234
this->a = 10;
235235
T = 13; // expected-error {{cannot assign to non-static data member 'T' with const-qualified type}} \
236236
// ref-error {{cannot assign to non-static data member 'T' with const-qualified type}}
237237
}
238238
};
239239
constexpr Foo F; // expected-error {{must be initialized by a constant expression}} \
240-
// FIXME: The following note is wrong. \
241-
// expected-note {{undefined constructor 'Foo' cannot be used in a constant expression}} \
242240
// ref-error {{must be initialized by a constant expression}}
243241

244242

clang/test/AST/Interp/records.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,10 +1232,9 @@ namespace InheritedConstructor {
12321232
namespace InvalidCtorInitializer {
12331233
struct X {
12341234
int Y;
1235-
constexpr X() // expected-note {{declared here}}
1235+
constexpr X()
12361236
: Y(fo_o_()) {} // both-error {{use of undeclared identifier 'fo_o_'}}
12371237
};
12381238
// no crash on evaluating the constexpr ctor.
1239-
constexpr int Z = X().Y; // both-error {{constexpr variable 'Z' must be initialized by a constant expression}} \
1240-
// expected-note {{undefined constructor 'X'}}
1239+
constexpr int Z = X().Y; // both-error {{constexpr variable 'Z' must be initialized by a constant expression}}
12411240
}

0 commit comments

Comments
 (0)