go.tools/pointer: implement (reflect.Value).Call.

The implementation follows the basic pattern of an indirect
function call (genDynamicCall).

We use the same trick as SetFinalizer so that direct calls to
(r.V).Call, which are overwhelmingly the norm, are inlined.

Bug fix (and simplification): calling untag() to unbox a
reflect.Value is wrong for reflect.Values containing interfaces
(rare).  Now, we call untag for concrete types and typeFilter
for interface types, and we can use this pattern in all cases.
It corresponds to the ssa.TypeAssert operator, so we call
it typeAssert.  Added tests to cover this.

We also specialize reflect.{In,Out} when the operand is an int
literal.

+ Tests.

Also:
- make taggedValue() panic, not return nil, eliminating many checks.
  We call isTaggedValue for the one place that cares.
- pointer_test: recover from panics in Analyze() and dump the log.

R=crawshaw
CC=golang-dev
https://golang.org/cl/14426050
diff --git a/pointer/gen.go b/pointer/gen.go
index 7329d32..5a99534 100644
--- a/pointer/gen.go
+++ b/pointer/gen.go
@@ -182,7 +182,7 @@
 func (a *analysis) rtypeTaggedValue(obj nodeid) types.Type {
 	tDyn, t, _ := a.taggedValue(obj)
 	if tDyn != a.reflectRtypePtr {
-		panic(fmt.Sprintf("not a *reflect.rtype-tagged value: obj=n%d tag=%v payload=n%d", obj, tDyn, t))
+		panic(fmt.Sprintf("not a *reflect.rtype-tagged object: obj=n%d tag=%v payload=n%d", obj, tDyn, t))
 	}
 	return a.nodes[t].typ
 }
@@ -224,17 +224,22 @@
 	return id + nodeid(a.offsetOf(v.Type(), index))
 }
 
+// isTaggedObject reports whether object obj is a tagged object.
+func (a *analysis) isTaggedObject(obj nodeid) bool {
+	return a.nodes[obj].obj.flags&otTagged != 0
+}
+
 // taggedValue returns the dynamic type tag, the (first node of the)
 // payload, and the indirect flag of the tagged object starting at id.
-// It returns tDyn==nil if obj is not a tagged object.
+// Panic ensues if !isTaggedObject(id).
 //
-func (a *analysis) taggedValue(id nodeid) (tDyn types.Type, v nodeid, indirect bool) {
-	n := a.nodes[id]
+func (a *analysis) taggedValue(obj nodeid) (tDyn types.Type, v nodeid, indirect bool) {
+	n := a.nodes[obj]
 	flags := n.obj.flags
-	if flags&otTagged != 0 {
-		return n.typ, id + 1, flags&otIndirect != 0
+	if flags&otTagged == 0 {
+		panic(fmt.Sprintf("not a tagged object: n%d", obj))
 	}
-	return
+	return n.typ, obj + 1, flags&otIndirect != 0
 }
 
 // funcParams returns the first node of the params block of the
@@ -351,14 +356,16 @@
 	}
 }
 
-// typeFilter creates a typeFilter constraint of the form dst = src.(I).
-func (a *analysis) typeFilter(I types.Type, dst, src nodeid) {
-	a.addConstraint(&typeFilterConstraint{I, dst, src})
-}
-
-// untag creates an untag constraint of the form dst = src.(C).
-func (a *analysis) untag(C types.Type, dst, src nodeid, exact bool) {
-	a.addConstraint(&untagConstraint{C, dst, src, exact})
+// typeAssert creates a typeFilter or untag constraint of the form dst = src.(T):
+// typeFilter for an interface, untag for a concrete type.
+// The exact flag is specified as for untagConstraint.
+//
+func (a *analysis) typeAssert(T types.Type, dst, src nodeid, exact bool) {
+	if isInterface(T) {
+		a.addConstraint(&typeFilterConstraint{T, dst, src})
+	} else {
+		a.addConstraint(&untagConstraint{T, dst, src, exact})
+	}
 }
 
 // addConstraint adds c to the constraint set.
@@ -591,6 +598,15 @@
 			f:       a.valueNode(call.Args[1]),
 		})
 		return
+
+	case a.reflectValueCall:
+		// Inline (reflect.Value).Call so the call appears direct.
+		dotdotdot := false
+		ret := reflectCallImpl(a, caller, site, a.valueNode(call.Args[0]), a.valueNode(call.Args[1]), dotdotdot)
+		if result != 0 {
+			a.addressOf(result, ret)
+		}
+		return
 	}
 
 	// Ascertain the context (contour/cgnode) for a particular call.
@@ -700,7 +716,7 @@
 	// Unpack receiver into rtype
 	rtype := a.addOneNode(a.reflectRtypePtr, "rtype.recv", nil)
 	recv := a.valueNode(call.Value)
-	a.untag(a.reflectRtypePtr, rtype, recv, true)
+	a.typeAssert(a.reflectRtypePtr, rtype, recv, true)
 
 	// Look up the concrete method.
 	meth := a.reflectRtypePtr.MethodSet().Lookup(call.Method.Pkg(), call.Method.Name())
@@ -1007,12 +1023,7 @@
 		a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
 
 	case *ssa.TypeAssert:
-		T := instr.AssertedType
-		if _, ok := T.Underlying().(*types.Interface); ok {
-			a.typeFilter(T, a.valueNode(instr), a.valueNode(instr.X))
-		} else {
-			a.untag(T, a.valueNode(instr), a.valueNode(instr.X), true)
-		}
+		a.typeAssert(instr.AssertedType, a.valueNode(instr), a.valueNode(instr.X), true)
 
 	case *ssa.Slice:
 		a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)