[clang] [clang][Interp] Don't diagnose undefined functions when checking... (PR #75051)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 13 02:13:33 PST 2023
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/75051
>From b98a9d3a203bbcf56e81c7be7e2c011088095713 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 11 Dec 2023 15:08:32 +0100
Subject: [PATCH] [clang][Interp] Don't diagnose undefined functions when
checking...
... for a potential constant expression. They are not defined now, but
might be defined later when the function is actually called.
---
clang/lib/AST/Interp/Interp.cpp | 19 +++++++++++--------
clang/test/AST/Interp/functions.cpp | 11 +++++++++++
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 13b77e9a87725c..a82d1c3c7c622a 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -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();
@@ -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);
}
diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp
index ab562e70606b67..179a195098b132 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -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 {
More information about the cfe-commits
mailing list