[analyzer] Use Clang's evaluation for global constants and default arguments.

Previously, we were handling only simple integer constants for globals and
the smattering of implicitly-valued expressions handled by Environment for
default arguments. Now, we can use any integer constant expression that
Clang can evaluate, in addition to everything we handled before.

PR15094 / <rdar://problem/12830437>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175026 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index 873b046..f0e69dd 100644
--- a/test/Analysis/inline.cpp
+++ b/test/Analysis/inline.cpp
@@ -216,7 +216,7 @@
 
   class Secret {
   public:
-    static const int value = 42;
+    static const int value = 40 + 2;
     int get(int i = value) {
       return i;
     }
@@ -225,16 +225,40 @@
   void testMethod() {
     Secret obj;
     clang_analyzer_eval(obj.get(1) == 1); // expected-warning{{TRUE}}
-
-    // FIXME: Should be 'TRUE'. See PR13673 or <rdar://problem/11720796>.
-    clang_analyzer_eval(obj.get() == 42); // expected-warning{{UNKNOWN}}
-
-    // FIXME: Even if we constrain the variable, we still have a problem.
-    // See PR13385 or <rdar://problem/12156507>.
-    if (Secret::value != 42)
-      return;
+    clang_analyzer_eval(obj.get() == 42); // expected-warning{{TRUE}}
     clang_analyzer_eval(Secret::value == 42); // expected-warning{{TRUE}}
-    clang_analyzer_eval(obj.get() == 42); // expected-warning{{UNKNOWN}}
+  }
+
+  enum ABC {
+    A = 0,
+    B = 1,
+    C = 2
+  };
+
+  int enumUser(ABC input = B) {
+    return static_cast<int>(input);
+  }
+
+  void testEnum() {
+    clang_analyzer_eval(enumUser(C) == 2); // expected-warning{{TRUE}}
+    clang_analyzer_eval(enumUser() == 1); // expected-warning{{TRUE}}
+  }
+
+
+  int exprUser(int input = 2 * 4) {
+    return input;
+  }
+
+  int complicatedExprUser(int input = 2 * Secret::value) {
+    return input;
+  }
+
+  void testExprs() {
+    clang_analyzer_eval(exprUser(1) == 1); // expected-warning{{TRUE}}
+    clang_analyzer_eval(exprUser() == 8); // expected-warning{{TRUE}}
+
+    clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}}
+    clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}}
   }
 }