// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
This file contains the code to check for suspicious shifts.
*/

package main

import (
	"go/ast"
	"go/constant"
	"go/token"
	"go/types"
)

func init() {
	register("shift",
		"check for useless shifts",
		checkShift,
		binaryExpr, assignStmt)
}

func checkShift(f *File, node ast.Node) {
	switch node := node.(type) {
	case *ast.BinaryExpr:
		if node.Op == token.SHL || node.Op == token.SHR {
			checkLongShift(f, node, node.X, node.Y)
		}
	case *ast.AssignStmt:
		if len(node.Lhs) != 1 || len(node.Rhs) != 1 {
			return
		}
		if node.Tok == token.SHL_ASSIGN || node.Tok == token.SHR_ASSIGN {
			checkLongShift(f, node, node.Lhs[0], node.Rhs[0])
		}
	}
}

// checkLongShift checks if shift or shift-assign operations shift by more than
// the length of the underlying variable.
func checkLongShift(f *File, node ast.Node, x, y ast.Expr) {
	v := f.pkg.types[y].Value
	if v == nil {
		return
	}
	amt, ok := constant.Int64Val(v)
	if !ok {
		return
	}
	t := f.pkg.types[x].Type
	if t == nil {
		return
	}
	b, ok := t.Underlying().(*types.Basic)
	if !ok {
		return
	}
	var size int64
	var msg string
	switch b.Kind() {
	case types.Uint8, types.Int8:
		size = 8
	case types.Uint16, types.Int16:
		size = 16
	case types.Uint32, types.Int32:
		size = 32
	case types.Uint64, types.Int64:
		size = 64
	case types.Int, types.Uint, types.Uintptr:
		// These types may be as small as 32 bits, but no smaller.
		size = 32
		msg = "might be "
	default:
		return
	}
	if amt >= size {
		ident := f.gofmt(x)
		f.Badf(node.Pos(), "%s %stoo small for shift of %d", ident, msg, amt)
	}
}
