[CFE] Always clone subexpressions of unevaluated constants.

This makes the constant evaluator entirely non-destructive.

Change-Id: I0d347b51821e393e46c8d7782f0ccbc35712f0de
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96101
Reviewed-by: Kevin Millikin <kmillikin@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index f4361bd..e7c77df 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -1075,8 +1075,8 @@
     if (left is UnevaluatedConstant) {
       return unevaluated(
           node,
-          new LogicalExpression(
-              unique(left.expression), node.operator, node.right));
+          new LogicalExpression(unique(left.expression), node.operator,
+              cloner.clone(node.right)));
     }
     switch (node.operator) {
       case '||':
@@ -1138,8 +1138,11 @@
     } else if (condition is UnevaluatedConstant) {
       return unevaluated(
           node,
-          new ConditionalExpression(unique(condition.expression), node.then,
-              node.otherwise, node.staticType));
+          new ConditionalExpression(
+              unique(condition.expression),
+              cloner.clone(node.then),
+              cloner.clone(node.otherwise),
+              node.staticType));
     } else {
       throw new _AbortCurrentEvaluation(errorReporter.invalidDartType(
           contextChain, node, condition, typeEnvironment.boolType));
@@ -1211,7 +1214,7 @@
         if (target.isConst) {
           if (target.isInExternalLibrary && target.initializer == null) {
             // The variable is unavailable due to separate compilation.
-            return unevaluated(node, node);
+            return unevaluated(node, new StaticGet(target));
           }
           return runInsideContext(target, () {
             return _evaluateSubexpression(target.initializer);