If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
(x, y *operand, e Expr, op Operator)
| 935 | |
| 936 | // If e != nil, it must be the shift expression; it may be nil for non-constant shifts. |
| 937 | func (check *Checker) shift(x, y *operand, e Expr, op Operator) { |
| 938 | // TODO(gri) This function seems overly complex. Revisit. |
| 939 | |
| 940 | var xval constant.Value |
| 941 | if x.mode == constant_ { |
| 942 | xval = constant.ToInt(x.val) |
| 943 | } |
| 944 | |
| 945 | if allInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int { |
| 946 | // The lhs is of integer type or an untyped constant representable |
| 947 | // as an integer. Nothing to do. |
| 948 | } else { |
| 949 | // shift has no chance |
| 950 | check.errorf(x, invalidOp+"shifted operand %s must be integer", x) |
| 951 | x.mode = invalid |
| 952 | return |
| 953 | } |
| 954 | |
| 955 | // spec: "The right operand in a shift expression must have integer type |
| 956 | // or be an untyped constant representable by a value of type uint." |
| 957 | |
| 958 | // Provide a good error message for negative shift counts. |
| 959 | if y.mode == constant_ { |
| 960 | yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1 |
| 961 | if yval.Kind() == constant.Int && constant.Sign(yval) < 0 { |
| 962 | check.errorf(y, invalidOp+"negative shift count %s", y) |
| 963 | x.mode = invalid |
| 964 | return |
| 965 | } |
| 966 | } |
| 967 | |
| 968 | // Caution: Check for isUntyped first because isInteger includes untyped |
| 969 | // integers (was bug #43697). |
| 970 | if isUntyped(y.typ) { |
| 971 | check.convertUntyped(y, Typ[Uint]) |
| 972 | if y.mode == invalid { |
| 973 | x.mode = invalid |
| 974 | return |
| 975 | } |
| 976 | } else if !allInteger(y.typ) { |
| 977 | check.errorf(y, invalidOp+"shift count %s must be integer", y) |
| 978 | x.mode = invalid |
| 979 | return |
| 980 | } else if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) { |
| 981 | check.versionErrorf(y, "go1.13", invalidOp+"signed shift count %s", y) |
| 982 | x.mode = invalid |
| 983 | return |
| 984 | } |
| 985 | |
| 986 | if x.mode == constant_ { |
| 987 | if y.mode == constant_ { |
| 988 | // if either x or y has an unknown value, the result is unknown |
| 989 | if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown { |
| 990 | x.val = constant.MakeUnknown() |
| 991 | // ensure the correct type - see comment below |
| 992 | if !isInteger(x.typ) { |
| 993 | x.typ = Typ[UntypedInt] |
| 994 | } |
no test coverage detected