aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/lib/asan-dg.exp
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
committerBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
commit1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch)
treec607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/gcc/testsuite/lib/asan-dg.exp
parent283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff)
downloadtoolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/gcc/testsuite/lib/asan-dg.exp')
-rw-r--r--gcc-4.9/gcc/testsuite/lib/asan-dg.exp310
1 files changed, 310 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/lib/asan-dg.exp b/gcc-4.9/gcc/testsuite/lib/asan-dg.exp
new file mode 100644
index 000000000..9ba39db15
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/lib/asan-dg.exp
@@ -0,0 +1,310 @@
+# Copyright (C) 2012-2014 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Return 1 if compilation with -fsanitize=address is error-free for trivial
+# code, 0 otherwise.
+
+proc check_effective_target_faddress_sanitizer {} {
+ return [check_no_compiler_messages faddress_sanitizer object {
+ void foo (void) { }
+ } "-fsanitize=address"]
+}
+
+#
+# asan_link_flags -- compute library path and flags to find libasan.
+# (originally from g++.exp)
+#
+
+proc asan_link_flags { paths } {
+ global srcdir
+ global ld_library_path
+ global shlib_ext
+
+ set gccpath ${paths}
+ set flags ""
+
+ set shlib_ext [get_shlib_extension]
+
+ if { $gccpath != "" } {
+ if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"]
+ || [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.${shlib_ext}"] } {
+ append flags " -B${gccpath}/libsanitizer/ "
+ append flags " -B${gccpath}/libsanitizer/asan/ "
+ append flags " -L${gccpath}/libsanitizer/asan/.libs "
+ append ld_library_path ":${gccpath}/libsanitizer/asan/.libs"
+ }
+ } else {
+ global tool_root_dir
+
+ set libasan [lookfor_file ${tool_root_dir} libasan]
+ if { $libasan != "" } {
+ append flags "-L${libasan} "
+ append ld_library_path ":${libasan}"
+ }
+ }
+
+ set_ld_library_path_env_vars
+
+ return "$flags"
+}
+
+#
+# asan_init -- called at the start of each subdir of tests
+#
+
+proc asan_init { args } {
+ global TEST_ALWAYS_FLAGS
+ global ALWAYS_CXXFLAGS
+ global TOOL_OPTIONS
+ global asan_saved_TEST_ALWAYS_FLAGS
+
+ set link_flags ""
+ if ![is_remote host] {
+ if [info exists TOOL_OPTIONS] {
+ set link_flags "[asan_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
+ } else {
+ set link_flags "[asan_link_flags [get_multilibs]]"
+ }
+ }
+
+ if [info exists TEST_ALWAYS_FLAGS] {
+ set asan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
+ }
+ if [info exists ALWAYS_CXXFLAGS] {
+ set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
+ set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=address -g}" $ALWAYS_CXXFLAGS]
+ } else {
+ if [info exists TEST_ALWAYS_FLAGS] {
+ set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $TEST_ALWAYS_FLAGS"
+ } else {
+ set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g"
+ }
+ }
+ if { $link_flags != "" } {
+ return 1
+ }
+ return 0
+}
+
+#
+# asan_finish -- called at the start of each subdir of tests
+#
+
+proc asan_finish { args } {
+ global TEST_ALWAYS_FLAGS
+ global asan_saved_TEST_ALWAYS_FLAGS
+
+ if [info exists asan_saved_TEST_ALWAYS_FLAGS] {
+ set TEST_ALWAYS_FLAGS $asan_saved_TEST_ALWAYS_FLAGS
+ } else {
+ unset TEST_ALWAYS_FLAGS
+ }
+}
+
+# Symbolize lines like
+# #2 0xdeadbeef (/some/path/libsanitizer.so.0.0.0+0xbeef)
+# in $output using addr2line to
+# #2 0xdeadbeef in foobar file:123
+proc asan_symbolize { output } {
+ set addresses [regexp -inline -all -line "^ *#\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+)\[+\](0x\[0-9a-f\]+)\[)\]$" "$output"]
+ if { [llength $addresses] > 0 } {
+ set addr2line_name [find_binutils_prog addr2line]
+ set idx 1
+ while { $idx < [llength $addresses] } {
+ set key [regsub -all "\[\]\[\]" [lindex $addresses $idx] "\\\\&"]
+ set val [lindex $addresses [expr $idx + 1]]
+ lappend arr($key) $val
+ set idx [expr $idx + 3]
+ }
+ foreach key [array names arr] {
+ set args "-f -e $key $arr($key)"
+ set status [remote_exec host "$addr2line_name" "$args"]
+ if { [lindex $status 0] > 0 } continue
+ regsub -all "\r\n" [lindex $status 1] "\n" addr2line_output
+ regsub -all "\[\n\r\]BFD: \[^\n\r\]*" $addr2line_output "" addr2line_output
+ regsub -all "^BFD: \[^\n\r\]*\[\n\r\]" $addr2line_output "" addr2line_output
+ set addr2line_output [regexp -inline -all -line "^\[^\n\r]*" $addr2line_output]
+ set idx 0
+ foreach val $arr($key) {
+ if { [expr $idx + 1] < [llength $addr2line_output] } {
+ set fnname [lindex $addr2line_output $idx]
+ set fileline [lindex $addr2line_output [expr $idx + 1]]
+ if { "$fnname" != "??" } {
+ set newkey "$key+$val"
+ set repl($newkey) "$fnname $fileline"
+ }
+ set idx [expr $idx + 2]
+ }
+ }
+ }
+ set idx 0
+ set new_output ""
+ while {[regexp -start $idx -indices " #\[0-9\]+ 0x\[0-9a-f\]+ \[(\](\[^)\]+\[+\]0x\[0-9a-f\]+)\[)\]" "$output" -> addr] > 0} {
+ set low [lindex $addr 0]
+ set high [lindex $addr 1]
+ set val [string range "$output" $low $high]
+ append new_output [string range "$output" $idx [expr $low - 2]]
+ if [info exists repl($val)] {
+ append new_output "in $repl($val)"
+ } else {
+ append new_output "($val)"
+ }
+ set idx [expr $high + 2]
+ }
+ append new_output [string range "$output" $idx [string length "$output"]]
+ return "$new_output"
+ }
+ return "$output"
+}
+
+# Return a list of gtest tests, printed in the form
+# DEJAGNU_GTEST_TEST AddressSanitizer_SimpleDeathTest
+# DEJAGNU_GTEST_TEST AddressSanitizer_VariousMallocsTest
+proc asan_get_gtest_test_list { output } {
+ set idx 0
+ set ret ""
+ while {[regexp -start $idx -indices "DEJAGNU_GTEST_TEST (\[^\n\r\]*)(\r\n|\n|\r)" "$output" -> testname] > 0} {
+ set low [lindex $testname 0]
+ set high [lindex $testname 1]
+ set val [string range "$output" $low $high]
+ lappend ret $val
+ set idx [expr $high + 1]
+ }
+ return $ret
+}
+
+# Return a list of gtest EXPECT_DEATH tests, printed in the form
+# DEJAGNU_GTEST_EXPECT_DEATH1 statement DEJAGNU_GTEST_EXPECT_DEATH1 regexp DEJAGNU_GTEST_EXPECT_DEATH1
+# DEJAGNU_GTEST_EXPECT_DEATH2 other statement DEJAGNU_GTEST_EXPECT_DEATH2 other regexp DEJAGNU_GTEST_EXPECT_DEATH2
+proc asan_get_gtest_expect_death_list { output } {
+ set idx 0
+ set ret ""
+ while {[regexp -start $idx -indices "DEJAGNU_GTEST_EXPECT_DEATH(\[0-9\]*)" "$output" -> id ] > 0} {
+ set low [lindex $id 0]
+ set high [lindex $id 1]
+ set val_id [string range "$output" $low $high]
+ if {[regexp -start $low -indices "$val_id (.*) DEJAGNU_GTEST_EXPECT_DEATH$val_id (.*) DEJAGNU_GTEST_EXPECT_DEATH$val_id\[\n\r\]" "$output" whole statement regexpr ] == 0} { break }
+ set low [lindex $statement 0]
+ set high [lindex $statement 1]
+ set val_statement [string range "$output" $low $high]
+ set low [lindex $regexpr 0]
+ set high [lindex $regexpr 1]
+ set val_regexpr [string range "$output" $low $high]
+ lappend ret [list "$val_id" "$val_statement" "$val_regexpr"]
+ set idx [lindex $whole 1]
+ }
+ return $ret
+}
+
+# Replace ${tool}_load with a wrapper so that we can symbolize the output.
+if { [info procs ${tool}_load] != [list] \
+ && [info procs saved_asan_${tool}_load] == [list] } {
+ rename ${tool}_load saved_asan_${tool}_load
+
+ proc ${tool}_load { program args } {
+ global tool
+ global asan_last_gtest_test_list
+ global asan_last_gtest_expect_death_list
+ set result [eval [list saved_asan_${tool}_load $program] $args]
+ set output [lindex $result 1]
+ set symbolized_output [asan_symbolize "$output"]
+ set asan_last_gtest_test_list [asan_get_gtest_test_list "$output"]
+ set asan_last_gtest_expect_death_list [asan_get_gtest_expect_death_list "$output"]
+ set result [list [lindex $result 0] $symbolized_output]
+ return $result
+ }
+}
+
+# Utility for running gtest asan emulation under dejagnu, invoked via dg-final.
+# Call pass if variable has the desired value, otherwise fail.
+#
+# Argument 0 handles expected failures and the like
+proc asan-gtest { args } {
+ global tool
+ global asan_last_gtest_test_list
+ global asan_last_gtest_expect_death_list
+
+ if { ![info exists asan_last_gtest_test_list] } { return }
+ if { [llength $asan_last_gtest_test_list] == 0 } { return }
+ if { ![isnative] || [is_remote target] } { return }
+
+ set gtest_test_list $asan_last_gtest_test_list
+ unset asan_last_gtest_test_list
+
+ if { [llength $args] >= 1 } {
+ switch [dg-process-target [lindex $args 0]] {
+ "S" { }
+ "N" { return }
+ "F" { setup_xfail "*-*-*" }
+ "P" { }
+ }
+ }
+
+ # This assumes that we are three frames down from dg-test, and that
+ # it still stores the filename of the testcase in a local variable "name".
+ # A cleaner solution would require a new DejaGnu release.
+ upvar 2 name testcase
+ upvar 2 prog prog
+
+ set output_file "[file rootname [file tail $prog]].exe"
+
+ foreach gtest $gtest_test_list {
+ set testname "$testcase $gtest"
+ set status -1
+
+ setenv DEJAGNU_GTEST_ARG "$gtest"
+ set result [${tool}_load ./$output_file $gtest]
+ unsetenv DEJAGNU_GTEST_ARG
+ set status [lindex $result 0]
+ set output [lindex $result 1]
+ if { "$status" == "pass" } {
+ pass "$testname execution test"
+ if { [info exists asan_last_gtest_expect_death_list] } {
+ set gtest_expect_death_list $asan_last_gtest_expect_death_list
+ foreach gtest_death $gtest_expect_death_list {
+ set id [lindex $gtest_death 0]
+ set testname "$testcase $gtest [lindex $gtest_death 1]"
+ set regexpr [lindex $gtest_death 2]
+ set status -1
+
+ setenv DEJAGNU_GTEST_ARG "$gtest:$id"
+ set result [${tool}_load ./$output_file "$gtest:$id"]
+ unsetenv DEJAGNU_GTEST_ARG
+ set status [lindex $result 0]
+ set output [lindex $result 1]
+ if { "$status" == "fail" } {
+ pass "$testname execution test"
+ if { ![regexp $regexpr ${output}] } {
+ fail "$testname output pattern test"
+ send_log "Output should match: $regexpr\n"
+ } else {
+ pass "$testname output pattern test"
+ }
+ } elseif { "$status" == "pass" } {
+ fail "$testname execution test"
+ } else {
+ $status "$testname execution test"
+ }
+ }
+ }
+ } else {
+ $status "$testname execution test"
+ }
+ unset asan_last_gtest_expect_death_list
+ }
+
+ return
+}