Skip to content

Commit a897700

Browse files
authored
[clang][Interp] Don't diagnose undefined functions when checking... (#75051)
... for a potential constant expression. They are not defined now, but might be defined later when the function is actually called.
1 parent bb18611 commit a897700

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

clang/lib/AST/Interp/Interp.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,6 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
350350
}
351351

352352
if (!F->isConstexpr()) {
353-
// Don't emit anything if we're checking for a potential constant
354-
// expression. That will happen later when actually executing.
355-
if (S.checkingPotentialConstantExpression())
356-
return false;
357-
358353
const SourceLocation &Loc = S.Current->getLocation(OpPC);
359354
if (S.getLangOpts().CPlusPlus11) {
360355
const FunctionDecl *DiagDecl = F->getDecl();
@@ -371,13 +366,21 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
371366
// FIXME: If DiagDecl is an implicitly-declared special member function
372367
// or an inheriting constructor, we should be much more explicit about why
373368
// it's not constexpr.
374-
if (CD && CD->isInheritingConstructor())
369+
if (CD && CD->isInheritingConstructor()) {
375370
S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1)
376371
<< CD->getInheritedConstructor().getConstructor()->getParent();
377-
else
372+
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
373+
} else {
374+
// Don't emit anything if the function isn't defined and we're checking
375+
// for a constant expression. It might be defined at the point we're
376+
// actually calling it.
377+
if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression())
378+
return false;
379+
378380
S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1)
379381
<< DiagDecl->isConstexpr() << (bool)CD << DiagDecl;
380-
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
382+
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
383+
}
381384
} else {
382385
S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
383386
}

clang/test/AST/Interp/functions.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,17 @@ namespace InvalidCall {
267267
// ref-error {{must be initialized by a constant expression}} \
268268
// ref-note {{in call to 'SS()'}}
269269

270+
271+
/// This should not emit a diagnostic.
272+
constexpr int f();
273+
constexpr int a() {
274+
return f();
275+
}
276+
constexpr int f() {
277+
return 5;
278+
}
279+
static_assert(a() == 5, "");
280+
270281
}
271282

272283
namespace CallWithArgs {

0 commit comments

Comments
 (0)