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}}
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to