# Copyright 2022-2025 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Check the format of the error message given when a breakpoint
# condition fails.
#
# In this case the breakpoint condition does not make use of inferior
# function calls, instead, the expression used for the breakpoint
# condition will throw an error when evaluated.
#
# We check that the correct breakpoint number appears in the error
# message, and that the error is reported at the correct source
# location.

standard_testfile

if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
	  {debug c++}] == -1 } {
    return
}

# Run to main so that we connect to the target if using 'target
# remote'.  This means that the is_address_zero_readable, and the
# 'show breakpoint condition-evaluation' checks below will be
# performed with the remote connection in place.
if { ![runto_main] } {
    return -1
}

# This test relies on reading address zero triggering a SIGSEGV.
if { [is_address_zero_readable] } {
    return
}

proc run_test { cond_eval access_type bpexpr nloc } {
    clean_restart ${::binfile}

    if { ![runto_main] } {
	return -1
    }

    if { $cond_eval ne "auto" } {
	gdb_test_no_output "set breakpoint condition-evaluation ${cond_eval}"
    }

    # Setup the conditional breakpoint and record its number.
    gdb_breakpoint "${bpexpr} if (*(${access_type} *) 0) == 0"

    # This test aims to test that GDB displays the correct breakpoint number
    # and location when there is an error testing a breakpoint condition,
    # so it is important to hardcode the breakpoint number into the regex,
    # along with the location, if applicable.
    set bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"]

    if { $nloc > 1 } {
	# We hardcode location 2 because, for some reason, Clang will always
	# order the debug information so we hit the second location.  For
	# simplicity the .c is ordered in such a way that GCC will also order
	# the debug info to have us land on location 2.
	gdb_test "continue" \
	    [multi_line \
		 "Continuing\\." \
		 "Error in testing condition for breakpoint ${bp_num}.2:" \
		 "Cannot access memory at address 0x0" \
		 "" \
		 "(Thread \[^\r\n\]+ hit )?Breakpoint ${bp_num}.2, foo \\(c=49 ...\\) at \[^\r\n\]+:\[0-9\]+" \
		 "${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"]
    } else {
	gdb_test "continue" \
	    [multi_line \
		 "Continuing\\." \
		 "Error in testing condition for breakpoint ${bp_num}:" \
		 "Cannot access memory at address 0x0" \
		 "" \
		 "(Thread \[^\r\n\]+ hit )?Breakpoint ${bp_num}, bar \\(\\) at \[^\r\n\]+:\[0-9\]+" \
		 "${::decimal}\\s+\[^\r\n\]+ breakpoint here\\. \[^\r\n\]+"]
    }
}

# If we're using a remote target then conditions could be evaulated
# locally on the host, or on the remote target.  Otherwise, conditions
# are always evaluated locally.
#
# Using "auto" will select the target if the target supports condition
# evaluation, otherwise, the local host will be used.
#
# So, we always include "auto", but then we look at the output of
# 'show breakpoint condition-evaluation', if this tells us that "auto"
# is using the target, then we specifically add "host" to the list of
# modes to check.

set cond_eval_modes { "auto" }

gdb_test_multiple "show breakpoint condition-evaluation" "" {
    -re -wrap "Breakpoint condition evaluation mode is auto \\(currently target\\)\\." {
	lappend cond_eval_modes "host"
	pass $gdb_test_name
    }

    -re -wrap "Breakpoint condition evaluation mode is auto \\(currently host\\)\\." {
	pass $gdb_test_name
    }
}

# Where the breakpoint will be placed.
set bp_line_multi_loc "foo"
set bp_line_single_loc [gdb_get_line_number "Single-location breakpoint here"]

foreach_with_prefix access_type { "char" "short" "int" "long long" } {
    foreach_with_prefix cond_eval $cond_eval_modes {
	with_test_prefix "multi-loc" {
	    run_test $cond_eval $access_type $bp_line_multi_loc 2
	}
	with_test_prefix "single-loc" {
	    run_test $cond_eval $access_type "${srcfile}:${bp_line_single_loc}" 1
	}
    }
}
