// 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.

// Package shift defines an Analyzer that checks for shifts that exceed
// the width of an integer.
package shift

// TODO(adonovan): integrate with ctrflow (CFG-based) dead code analysis. May
// have impedance mismatch due to its (non-)treatment of constant
// expressions (such as runtime.GOARCH=="386").

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

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/inspect"
	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/internal/typeparams"
)

const Doc = "check for shifts that equal or exceed the width of the integer"

var Analyzer = &analysis.Analyzer{
	Name:     "shift",
	Doc:      Doc,
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

func run(pass *analysis.Pass) (interface{}, error) {
	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

	// Do a complete pass to compute dead nodes.
	dead := make(map[ast.Node]bool)
	nodeFilter := []ast.Node{
		(*ast.IfStmt)(nil),
		(*ast.SwitchStmt)(nil),
	}
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		// TODO(adonovan): move updateDead into this file.
		updateDead(pass.TypesInfo, dead, n)
	})

	nodeFilter = []ast.Node{
		(*ast.AssignStmt)(nil),
		(*ast.BinaryExpr)(nil),
	}
	inspect.Preorder(nodeFilter, func(node ast.Node) {
		if dead[node] {
			// Skip shift checks on unreachable nodes.
			return
		}

		switch node := node.(type) {
		case *ast.BinaryExpr:
			if node.Op == token.SHL || node.Op == token.SHR {
				checkLongShift(pass, 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(pass, node, node.Lhs[0], node.Rhs[0])
			}
		}
	})
	return nil, nil
}

// checkLongShift checks if shift or shift-assign operations shift by more than
// the length of the underlying variable.
func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) {
	if pass.TypesInfo.Types[x].Value != nil {
		// Ignore shifts of constants.
		// These are frequently used for bit-twiddling tricks
		// like ^uint(0) >> 63 for 32/64 bit detection and compatibility.
		return
	}

	v := pass.TypesInfo.Types[y].Value
	if v == nil {
		return
	}
	amt, ok := constant.Int64Val(v)
	if !ok {
		return
	}
	t := pass.TypesInfo.Types[x].Type
	if t == nil {
		return
	}
	var structuralTypes []types.Type
	switch t := t.(type) {
	case *typeparams.TypeParam:
		terms, err := typeparams.StructuralTerms(t)
		if err != nil {
			return // invalid type
		}
		for _, term := range terms {
			structuralTypes = append(structuralTypes, term.Type())
		}
	default:
		structuralTypes = append(structuralTypes, t)
	}
	sizes := make(map[int64]struct{})
	for _, t := range structuralTypes {
		size := 8 * pass.TypesSizes.Sizeof(t)
		sizes[size] = struct{}{}
	}
	minSize := int64(math.MaxInt64)
	for size := range sizes {
		if size < minSize {
			minSize = size
		}
	}
	if amt >= minSize {
		ident := analysisutil.Format(pass.Fset, x)
		qualifier := ""
		if len(sizes) > 1 {
			qualifier = "may be "
		}
		pass.ReportRangef(node, "%s (%s%d bits) too small for shift of %d", ident, qualifier, minSize, amt)
	}
}
