Promote constant expression shift type based on both operands

The shift evaluation needs to use a promoted type for both operands in
case of a mismatch.
The number of bits to shift is now checked for the shift right
operation.

Test: aidl_parser_fuzzer large_shift_overflow && atest -p
Bug: 168285430

Change-Id: I8bbe7ea66415d380066bc68566601a35487ce764
diff --git a/aidl_const_expressions.cpp b/aidl_const_expressions.cpp
index 5626e40..48980f5 100644
--- a/aidl_const_expressions.cpp
+++ b/aidl_const_expressions.cpp
@@ -101,7 +101,7 @@
   T operator==(T o) { return mValue == o; }
   T operator!=(T o) { return mValue != o; }
   T operator>>(T o) {
-    if (o < 0) {
+    if (o < 0 || o > static_cast<T>(sizeof(T) * 8)) {
       mOverflowed = true;
       return 0;
     }
@@ -217,8 +217,7 @@
 }
 
 template <class T>
-bool handleShift(const AidlConstantValue& context, T lval, const string& op, int64_t rval,
-                 int64_t* out) {
+bool handleShift(const AidlConstantValue& context, T lval, const string& op, T rval, int64_t* out) {
   // just cast rval to int64_t and it should fit.
   COMPUTE_BINARY(T, >>)
   COMPUTE_BINARY(T, <<)
@@ -889,9 +888,10 @@
   // CASE: << >>
   string newOp = op_;
   if (OP_IS_BIN_SHIFT) {
-    final_type_ = IntegralPromotion(left_val_->final_type_);
-    // instead of promoting rval, simply casting it to int64 should also be good.
-    int64_t numBits = right_val_->cast<int64_t>();
+    // promoted kind for both operands.
+    final_type_ = UsualArithmeticConversion(IntegralPromotion(left_val_->final_type_),
+                                            IntegralPromotion(right_val_->final_type_));
+    auto numBits = right_val_->final_value_;
     if (numBits < 0) {
       // shifting with negative number of bits is undefined in C. In AIDL it
       // is defined as shifting into the other direction.
@@ -899,9 +899,9 @@
       numBits = -numBits;
     }
 
-#define CASE_SHIFT(__type__)                                                                \
-  return handleShift(*this, static_cast<__type__>(left_val_->final_value_), newOp, numBits, \
-                     &final_value_);
+#define CASE_SHIFT(__type__)                                                       \
+  return handleShift(*this, static_cast<__type__>(left_val_->final_value_), newOp, \
+                     static_cast<__type__>(numBits), &final_value_);
 
     SWITCH_KIND(final_type_, CASE_SHIFT, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
                 is_valid_ = false; return false;)