Skip to content

Commit

Permalink
[clang][Interp] Don't diagnose undefined functions when checking... (#…
Browse files Browse the repository at this point in the history
…75051)

... for a potential constant expression. They are not defined now, but
might be defined later when the function is actually called.
  • Loading branch information
tbaederr committed Dec 13, 2023
1 parent bb18611 commit a897700
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
19 changes: 11 additions & 8 deletions clang/lib/AST/Interp/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,6 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
}

if (!F->isConstexpr()) {
// Don't emit anything if we're checking for a potential constant
// expression. That will happen later when actually executing.
if (S.checkingPotentialConstantExpression())
return false;

const SourceLocation &Loc = S.Current->getLocation(OpPC);
if (S.getLangOpts().CPlusPlus11) {
const FunctionDecl *DiagDecl = F->getDecl();
Expand All @@ -371,13 +366,21 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
// FIXME: If DiagDecl is an implicitly-declared special member function
// or an inheriting constructor, we should be much more explicit about why
// it's not constexpr.
if (CD && CD->isInheritingConstructor())
if (CD && CD->isInheritingConstructor()) {
S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1)
<< CD->getInheritedConstructor().getConstructor()->getParent();
else
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
} else {
// Don't emit anything if the function isn't defined and we're checking
// for a constant expression. It might be defined at the point we're
// actually calling it.
if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression())
return false;

S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1)
<< DiagDecl->isConstexpr() << (bool)CD << DiagDecl;
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
}
} else {
S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
}
Expand Down
11 changes: 11 additions & 0 deletions clang/test/AST/Interp/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,17 @@ namespace InvalidCall {
// ref-error {{must be initialized by a constant expression}} \
// ref-note {{in call to 'SS()'}}


/// This should not emit a diagnostic.
constexpr int f();
constexpr int a() {
return f();
}
constexpr int f() {
return 5;
}
static_assert(a() == 5, "");

}

namespace CallWithArgs {
Expand Down

0 comments on commit a897700

Please sign in to comment.