Fix a code generator bug caused by the new CSE optimization.  Add test cases
to prevent a recurrence. (CVS 5011)

FossilOrigin-Name: d04246a46399e839e70b1bd57e209f80143f0d5b
diff --git a/src/expr.c b/src/expr.c
index 3002ef7..f58743b 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.366 2008/04/11 15:36:03 drh Exp $
+** $Id: expr.c,v 1.367 2008/04/15 12:14:22 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2104,6 +2104,24 @@
 }
 
 /*
+** If the last instruction coded is an ephemeral copy of any of
+** the registers in the nReg registers beginning with iReg, then
+** convert the last instruction from OP_SCopy to OP_Copy.
+*/
+void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
+  int addr;
+  VdbeOp *pOp;
+  Vdbe *v;
+
+  v = pParse->pVdbe;
+  addr = sqlite3VdbeCurrentAddr(v);
+  pOp = sqlite3VdbeGetOp(v, addr-1);
+  if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
+    pOp->opcode = OP_Copy;
+  }
+}
+
+/*
 ** Generate code into the current Vdbe to evaluate the given
 ** expression.  Attempt to store the results in register "target".
 ** Return the register where results are stored.
@@ -2374,7 +2392,7 @@
       if( pList ){
         nExpr = pList->nExpr;
         r1 = sqlite3GetTempRange(pParse, nExpr);
-        sqlite3ExprCodeExprList(pParse, pList, r1);
+        sqlite3ExprCodeExprList(pParse, pList, r1, 1);
       }else{
         nExpr = r1 = 0;
       }
@@ -2804,7 +2822,8 @@
 int sqlite3ExprCodeExprList(
   Parse *pParse,     /* Parsing context */
   ExprList *pList,   /* The expression list to be coded */
-  int target         /* Where to write results */
+  int target,        /* Where to write results */
+  int doHardCopy     /* Call sqlite3ExprHardCopy on each element if true */
 ){
   struct ExprList_item *pItem;
   int i, n;
@@ -2814,9 +2833,9 @@
   }
   assert( target>0 );
   n = pList->nExpr;
-  for(pItem=pList->a, i=n; i>0; i--, pItem++){
-    sqlite3ExprCode(pParse, pItem->pExpr, target);
-    target++;
+  for(pItem=pList->a, i=0; i<n; i++, pItem++){
+    sqlite3ExprCode(pParse, pItem->pExpr, target+i);
+    if( doHardCopy ) sqlite3ExprHardCopy(pParse, target, n);
   }
   return n;
 }