// buildrun -t 45

//go:build !js && !wasip1
// +build !js,!wasip1

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

// Ensure that runtime traceback does not infinite loop for
// the testcase below.

package main

import (
	"bytes"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
)

const prog = `

package main

import "context"

var gpi *int

type nAO struct {
	eE bool
}

type NAO func(*nAO)

func WEA() NAO {
	return func(o *nAO) { o.eE = true }
}

type R struct {
	cM *CM
}

type CM int

type A string

func (m *CM) NewA(ctx context.Context, cN string, nn *nAO, opts ...NAO) (*A, error) {
	for _, o := range opts {
		o(nn)
	}
	s := A("foo")
	return &s, nil
}

func (r *R) CA(ctx context.Context, cN string, nn *nAO) (*int, error) {
	cA, err := r.cM.NewA(ctx, cN, nn, WEA(), WEA())
	if err == nil {
		return nil, err
	}
	println(cA)
	x := int(42)
	return &x, nil
}

func main() {
	c := CM(1)
	r := R{cM: &c}
	var ctx context.Context
	nnr := nAO{}
	pi, err := r.CA(ctx, "foo", nil)
	if err != nil {
		panic("bad")
	}
	println(nnr.eE)
	gpi = pi
}
`

func main() {
	dir, err := ioutil.TempDir("", "46234")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(dir)

	file := filepath.Join(dir, "main.go")
	if err := ioutil.WriteFile(file, []byte(prog), 0655); err != nil {
		log.Fatalf("Write error %v", err)
	}

	cmd := exec.Command("go", "run", file)
	output, err := cmd.CombinedOutput()
	if err == nil {
		log.Fatalf("Passed, expected an error")
	}

	want := []byte("nil pointer dereference")
	if !bytes.Contains(output, want) {
		log.Fatalf("Unmatched error message %q:\nin\n%s\nError: %v", want, output, err)
	}
}
