[clang] cb70343 - [clang][Interp] Add back Run() call

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 25 08:02:21 PST 2023


Author: Timm Bäder
Date: 2023-01-25T17:01:55+01:00
New Revision: cb703434cbdc71beb02a7b555083f3e160a13363

URL: https://github.com/llvm/llvm-project/commit/cb703434cbdc71beb02a7b555083f3e160a13363
DIFF: https://github.com/llvm/llvm-project/commit/cb703434cbdc71beb02a7b555083f3e160a13363.diff

LOG: [clang][Interp] Add back Run() call

We need to run the functions we compiled immediately after to check if
they can ever be a constant expression.

Differential Revision: https://reviews.llvm.org/D140724

Added: 
    

Modified: 
    clang/lib/AST/Interp/Context.cpp
    clang/lib/AST/Interp/Interp.cpp
    clang/lib/AST/Interp/Interp.h
    clang/test/AST/Interp/arrays.cpp
    clang/test/AST/Interp/literals.cpp
    clang/test/AST/Interp/records.cpp
    clang/test/AST/Interp/shifts.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index 8d1c077e1817..dcf41a5c4020 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -42,6 +42,11 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) {
     }
   }
 
+  APValue DummyResult;
+  if (!Run(Parent, Func, DummyResult)) {
+    return false;
+  }
+
   return Func->isConstexpr();
 }
 

diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 31f141b9dde3..77b85d81c5f8 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -342,6 +342,11 @@ 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();

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 9613eafdb591..78a65b7995db 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1311,6 +1311,8 @@ inline bool This(InterpState &S, CodePtr OpPC) {
 
 inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
   assert(S.Current->getFunction()->hasRVO());
+  if (S.checkingPotentialConstantExpression())
+    return false;
   S.Stk.push<Pointer>(S.Current->getRVOPtr());
   return true;
 }
@@ -1383,9 +1385,11 @@ inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) {
   Pointer ThisPtr;
   if (Func->hasThisPointer()) {
     ThisPtr = NewFrame->getThis();
-    if (!CheckInvoke(S, PC, ThisPtr)) {
+    if (!CheckInvoke(S, PC, ThisPtr))
+      return false;
+
+    if (S.checkingPotentialConstantExpression())
       return false;
-    }
   }
 
   if (!CheckCallable(S, PC, Func))

diff  --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index accef60e38d6..413ab2fa45d8 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -209,7 +209,8 @@ class AU {
 public:
   int a;
   constexpr AU() : a(5 / 0) {} // expected-warning {{division by zero is undefined}} \
-                               // expected-note {{division by zero}} \
+                               // expected-note 2{{division by zero}} \
+                               // expected-error {{never produces a constant expression}} \
                                // ref-error {{never produces a constant expression}} \
                                // ref-note 2{{division by zero}} \
                                // ref-warning {{division by zero is undefined}}
@@ -296,10 +297,11 @@ namespace IncDec {
   }
   static_assert(getSecondToLast2() == 3, "");
 
-  constexpr int bad1() { // ref-error {{never produces a constant expression}}
+  constexpr int bad1() { // ref-error {{never produces a constant expression}} \
+                         // expected-error {{never produces a constant expression}}
     const int *e =  E + 3;
     e++; // This is fine because it's a one-past-the-end pointer
-    return *e; // expected-note {{read of dereferenced one-past-the-end pointer}} \
+    return *e; // expected-note 2{{read of dereferenced one-past-the-end pointer}} \
                // ref-note 2{{read of dereferenced one-past-the-end pointer}}
   }
   static_assert(bad1() == 0, ""); // expected-error {{not an integral constant expression}} \
@@ -307,9 +309,10 @@ namespace IncDec {
                                   // ref-error {{not an integral constant expression}} \
                                   // ref-note {{in call to}}
 
-  constexpr int bad2() { // ref-error {{never produces a constant expression}}
+  constexpr int bad2() { // ref-error {{never produces a constant expression}} \
+                         // expected-error {{never produces a constant expression}}
     const int *e = E + 4;
-    e++; // expected-note {{cannot refer to element 5 of array of 4 elements}} \
+    e++; // expected-note 2{{cannot refer to element 5 of array of 4 elements}} \
          // ref-note 2{{cannot refer to element 5 of array of 4 elements}}
     return *e; // This is UB as well
   }
@@ -319,9 +322,10 @@ namespace IncDec {
                                   // ref-note {{in call to}}
 
 
-  constexpr int bad3() { // ref-error {{never produces a constant expression}}
+  constexpr int bad3() { // ref-error {{never produces a constant expression}} \
+                         // expected-error {{never produces a constant expression}}
     const int *e = E;
-    e--; // expected-note {{cannot refer to element -1 of array of 4 elements}} \
+    e--; // expected-note 2{{cannot refer to element -1 of array of 4 elements}} \
          // ref-note 2{{cannot refer to element -1 of array of 4 elements}}
     return *e; // This is UB as well
   }

diff  --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index 4ba6d750db78..c57485aecbf9 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -452,10 +452,11 @@ namespace IncDec {
   static_assert(uninit(), ""); // ref-error {{not an integral constant expression}} \
                                // ref-note {{in call to 'uninit()'}}
 
-  constexpr int OverFlow() { // ref-error {{never produces a constant expression}}
+  constexpr int OverFlow() { // ref-error {{never produces a constant expression}} \
+                             // expected-error {{never produces a constant expression}}
     int a = INT_MAX;
     ++a; // ref-note 2{{is outside the range}} \
-         // expected-note {{is outside the range}}
+         // expected-note 2{{is outside the range}}
     return -1;
   }
   static_assert(OverFlow() == -1, "");  // expected-error {{not an integral constant expression}} \
@@ -464,10 +465,11 @@ namespace IncDec {
                                         // ref-note {{in call to 'OverFlow()'}}
 
 
-  constexpr int UnderFlow() { // ref-error {{never produces a constant expression}}
+  constexpr int UnderFlow() { // ref-error {{never produces a constant expression}} \
+                              // expected-error {{never produces a constant expression}}
     int a = INT_MIN;
     --a; // ref-note 2{{is outside the range}} \
-         // expected-note {{is outside the range}}
+         // expected-note 2{{is outside the range}}
     return -1;
   }
   static_assert(UnderFlow() == -1, "");  // expected-error {{not an integral constant expression}} \

diff  --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp
index afd6b7527337..b5bd04ff1228 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -174,10 +174,11 @@ namespace thisPointer {
     constexpr int get12() { return 12; }
   };
 
-  constexpr int foo() { // ref-error {{never produces a constant expression}}
+  constexpr int foo() { // ref-error {{never produces a constant expression}} \
+                        // expected-error {{never produces a constant expression}}
     S *s = nullptr;
     return s->get12(); // ref-note 2{{member call on dereferenced null pointer}} \
-                       // expected-note {{member call on dereferenced null pointer}}
+                       // expected-note 2{{member call on dereferenced null pointer}}
 
   }
   static_assert(foo() == 12, ""); // ref-error {{not an integral constant expression}} \

diff  --git a/clang/test/AST/Interp/shifts.cpp b/clang/test/AST/Interp/shifts.cpp
index b1df7b85cc9f..8fa78beb9302 100644
--- a/clang/test/AST/Interp/shifts.cpp
+++ b/clang/test/AST/Interp/shifts.cpp
@@ -8,7 +8,9 @@
 
 namespace shifts {
   constexpr void test() { // ref-error {{constexpr function never produces a constant expression}} \
-                          // ref-cxx17-error {{constexpr function never produces a constant expression}}
+                          // ref-cxx17-error {{constexpr function never produces a constant expression}} \
+                          // expected-error {{constexpr function never produces a constant expression}} \
+                          // cxx17-error {{constexpr function never produces a constant expression}} \
 
     char c; // cxx17-warning {{uninitialized variable}} \
             // ref-cxx17-warning {{uninitialized variable}}
@@ -19,6 +21,8 @@ namespace shifts {
     c = 1 << -0;
     c = 1 >> -0;
     c = 1 << -1; // expected-warning {{shift count is negative}} \
+                 // expected-note {{negative shift count -1}} \
+                 // cxx17-note {{negative shift count -1}} \
                  // cxx17-warning {{shift count is negative}} \
                  // ref-warning {{shift count is negative}} \
                  // ref-note {{negative shift count -1}} \


        


More information about the cfe-commits mailing list