[clang] ce938fc - [clang][Interp] Diagnose functions without body like undefined ones
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 6 10:41:57 PDT 2024
Author: Timm Bäder
Date: 2024-06-06T19:41:41+02:00
New Revision: ce938fcbde547315af18a47a609c2e09ebfb4cec
URL: https://github.com/llvm/llvm-project/commit/ce938fcbde547315af18a47a609c2e09ebfb4cec
DIFF: https://github.com/llvm/llvm-project/commit/ce938fcbde547315af18a47a609c2e09ebfb4cec.diff
LOG: [clang][Interp] Diagnose functions without body like undefined ones
We only get a "reached end of constexpr function" diagnostic
otherwise.
Added:
Modified:
clang/lib/AST/Interp/Interp.cpp
clang/test/AST/Interp/cxx23.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 41bbaf83b11c8..49015b1dd63d3 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -538,7 +538,7 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
return false;
}
- if (!F->isConstexpr()) {
+ if (!F->isConstexpr() || !F->hasBody()) {
const SourceLocation &Loc = S.Current->getLocation(OpPC);
if (S.getLangOpts().CPlusPlus11) {
const FunctionDecl *DiagDecl = F->getDecl();
@@ -572,9 +572,10 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
S.checkingPotentialConstantExpression())
return false;
- // If the declaration is defined _and_ declared 'constexpr', the below
- // diagnostic doesn't add anything useful.
- if (DiagDecl->isDefined() && DiagDecl->isConstexpr())
+ // If the declaration is defined, declared 'constexpr' _and_ has a body,
+ // the below diagnostic doesn't add anything useful.
+ if (DiagDecl->isDefined() && DiagDecl->isConstexpr() &&
+ DiagDecl->hasBody())
return false;
S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1)
diff --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp
index c91d52c552b12..1efd784abbbe8 100644
--- a/clang/test/AST/Interp/cxx23.cpp
+++ b/clang/test/AST/Interp/cxx23.cpp
@@ -178,3 +178,25 @@ namespace ExplicitLambdaThis {
};
static_assert(f());
}
+
+namespace std {
+ struct strong_ordering {
+ int n;
+ constexpr operator int() const { return n; }
+ static const strong_ordering less, equal, greater;
+ };
+ constexpr strong_ordering strong_ordering::less = {-1};
+ constexpr strong_ordering strong_ordering::equal = {0};
+ constexpr strong_ordering strong_ordering::greater = {1};
+}
+
+namespace UndefinedThreeWay {
+ struct A {
+ friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default; // all-note {{declared here}}
+ };
+
+ constexpr std::strong_ordering operator<=>(const A&, const A&) noexcept;
+ constexpr std::strong_ordering (*test_a_threeway)(const A&, const A&) = &operator<=>;
+ static_assert(!(*test_a_threeway)(A(), A())); // all-error {{static assertion expression is not an integral constant expression}} \
+ // all-note {{undefined function 'operator<=>' cannot be used in a constant expression}}
+}
More information about the cfe-commits
mailing list