<div dir="ltr"><div dir="ltr">On Mon, 23 Sep 2019 at 14:52, Eli Friedman via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It looks like there's a similar crash with while loops, e.g. "while (int m)".  That isn't valid, of course, but we try to perform constexpr evaluation anyway.<br></blockquote><div><br></div><div>Yes. That's at least not really a regression; we've crashed for a long time on things like</div><div><br></div><div>constexpr int f() {<br>    switch (1) {<br>        while (int m = 1) {<br>            case 1:<br>            return m;<br>        }<br>    }<br>}<br><br>constexpr int k = f();<br></div><div><br></div><div>I guess it'd make sense to just treat this case as non-constant rather than asserting. (Though it does raise a question of what AST invariants it's safe to rely on from the constant evaluator.)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-Eli<br>
<br>
-----Original Message-----<br>
From: cfe-commits <<a href="mailto:cfe-commits-bounces@lists.llvm.org" target="_blank">cfe-commits-bounces@lists.llvm.org</a>> On Behalf Of Richard Smith via cfe-commits<br>
Sent: Friday, September 20, 2019 4:09 PM<br>
To: <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
Subject: [EXT] r372437 - Fix assertion failure when constant evaluation of a switch jumps over an<br>
<br>
Author: rsmith<br>
Date: Fri Sep 20 16:08:59 2019<br>
New Revision: 372437<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=372437&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=372437&view=rev</a><br>
Log:<br>
Fix assertion failure when constant evaluation of a switch jumps over an<br>
uninitialized variable in an init-statement of a 'for' or 'if'.<br>
<br>
Modified:<br>
    cfe/trunk/lib/AST/ExprConstant.cpp<br>
    cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=372437&r1=372436&r2=372437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=372437&r1=372436&r2=372437&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Sep 20 16:08:59 2019<br>
@@ -4131,6 +4131,21 @@ static EvalStmtResult EvaluateStmt(StmtR<br>
       // preceded by our switch label.<br>
       BlockScopeRAII Scope(Info);<br>
<br>
+      // Step into the init statement in case it brings an (uninitialized)<br>
+      // variable into scope.<br>
+      if (const Stmt *Init = IS->getInit()) {<br>
+        EvalStmtResult ESR = EvaluateStmt(Result, Info, Init, Case);<br>
+        if (ESR != ESR_CaseNotFound) {<br>
+          assert(ESR != ESR_Succeeded);<br>
+          return ESR;<br>
+        }<br>
+      }<br>
+<br>
+      // Condition variable must be initialized if it exists.<br>
+      // FIXME: We can skip evaluating the body if there's a condition<br>
+      // variable, as there can't be any case labels within it.<br>
+      // (The same is true for 'for' statements.)<br>
+<br>
       EvalStmtResult ESR = EvaluateStmt(Result, Info, IS->getThen(), Case);<br>
       if (ESR != ESR_CaseNotFound || !IS->getElse())<br>
         return ESR;<br>
@@ -4147,6 +4162,18 @@ static EvalStmtResult EvaluateStmt(StmtR<br>
<br>
     case Stmt::ForStmtClass: {<br>
       const ForStmt *FS = cast<ForStmt>(S);<br>
+      BlockScopeRAII Scope(Info);<br>
+<br>
+      // Step into the init statement in case it brings an (uninitialized)<br>
+      // variable into scope.<br>
+      if (const Stmt *Init = FS->getInit()) {<br>
+        EvalStmtResult ESR = EvaluateStmt(Result, Info, Init, Case);<br>
+        if (ESR != ESR_CaseNotFound) {<br>
+          assert(ESR != ESR_Succeeded);<br>
+          return ESR;<br>
+        }<br>
+      }<br>
+<br>
       EvalStmtResult ESR =<br>
           EvaluateLoopBody(Result, Info, FS->getBody(), Case);<br>
       if (ESR != ESR_Continue)<br>
<br>
Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp?rev=372437&r1=372436&r2=372437&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp?rev=372437&r1=372436&r2=372437&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp Fri Sep 20 16:08:59 2019<br>
@@ -620,4 +620,17 @@ namespace Uninit {<br>
   constexpr int s1 = switch_var(1);<br>
   constexpr int s2 = switch_var(2);<br>
   static_assert(s1 == 1 && s2 == 2);<br>
+<br>
+  constexpr bool switch_into_init_stmt() {<br>
+    switch (1) {<br>
+      if (int n; false) {<br>
+        for (int m; false;) {<br>
+        case 1:<br>
+          n = m = 1;<br>
+          return n == 1 && m == 1;<br>
+        }<br>
+      }<br>
+    }<br>
+  }<br>
+  static_assert(switch_into_init_stmt());<br>
 }<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>