From patchwork Fri Dec 11 16:28:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1415025 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=gIJKKjHL; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Csx6X1Lzdz9sSs for ; Sat, 12 Dec 2020 03:28:20 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 90AB2386EC3E; Fri, 11 Dec 2020 16:28:17 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf33.google.com (mail-qv1-xf33.google.com [IPv6:2607:f8b0:4864:20::f33]) by sourceware.org (Postfix) with ESMTPS id C35123857023 for ; Fri, 11 Dec 2020 16:28:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C35123857023 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qv1-xf33.google.com with SMTP id u16so4443418qvl.7 for ; Fri, 11 Dec 2020 08:28:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=WkrUZZxvs0ct6qVRmoHGy3ZlywiWGB7sMyswwj+fDeU=; b=gIJKKjHLB7tsy63LcPOlT7YlcKlgkcFYpcdcMJGzvll9S3/zJVjGLNsb+S86/jhnt3 5GJwMJG/qI7DRLsnjAHxOCuj7QOrhDxiSGL3EzwrZExC+9QB1eHyrMjldhoJXWUG/v7c 9Mfq22tpIWR1Is1Mx+zGavXqxLEnuvDx8WEtH/6id/V/I6iTWTxqkiIIhpGPSnDxARLP FsqhAf1thZr504uyJaGBU2DPrZ8QlNroi9QugfSXFgYuyxvWi17muolEQMl0iJ+cI6+m NvBn62IpZGQ3ftxGlh9/tM2v1L8Ok/e6klW0tUTBUcGvKI6jj2VibACVjYsMk966QRri wBNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=WkrUZZxvs0ct6qVRmoHGy3ZlywiWGB7sMyswwj+fDeU=; b=AqWNUCzCd25Puhj3EwB51RzLCkW8uUNw7T+Vq8kGjxtmXl3xtLWRrzQ1Mq6DgOGqeR 2YfIt8EK4hZtYlc+nMDx9MisgvMc4jJHKyFiMRIByOiSuG0jUUyJuLOHL4D3AvTogVWW a3j/VyE8ShSYvaic4c9QdIlUlJjMpZq+Nd82DJHnyN7GxtjMSUOJM2WZMCxRufCAW0eo +kHAteTNN1ESi3znSUQ5gmWaR3G6Qon2okm58o0ipYaO12rgNvkzOKXQZlBVD1lkLkfj M56sAnE8sAn3dh0fL7pYuMOh9agyRHdKZ9PFIVJ6Y8Sc920qVL0XlSRPZneJSluuSJix kOWg== X-Gm-Message-State: AOAM530eohFNFh8w/BX43xbi68VE1B4tVDiUYa3VQ6Ak/OOKmY3NnMpy ltRBr81zZKEhrNIwu/7ZWzw= X-Google-Smtp-Source: ABdhPJzuwQtd2vtkXB6Ts06DODEPRMzI9GBX5Fp+fnzbCL8NqOHgvk62sfRGtACfmcHHcMsAle5CXA== X-Received: by 2002:a05:6214:7ac:: with SMTP id v12mr16496765qvz.13.1607704093979; Fri, 11 Dec 2020 08:28:13 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:7d2d:1a8a:7a22:aa55? ([2620:10d:c091:480::1:e048]) by smtp.googlemail.com with ESMTPSA id b12sm3593027qtt.74.2020.12.11.08.28.12 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 11 Dec 2020 08:28:13 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: module test harness Message-ID: Date: Fri, 11 Dec 2020 11:28:11 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Here is the module test harness -- but no tests. gcc/testsuite/ * g++.dg/modules/modules.exp: New. diff --git c/gcc/testsuite/g++.dg/modules/modules.exp w/gcc/testsuite/g++.dg/modules/modules.exp new file mode 100644 index 00000000000..e2fd2a7fdd0 --- /dev/null +++ w/gcc/testsuite/g++.dg/modules/modules.exp @@ -0,0 +1,376 @@ +# Copyright (C) 2017, 2018 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 +# . +# +# Contributed by Nathan Sidwell while at Facebook + + +# Test C++ modules, which requires multiple TUs +# +# A test case might consist of multiple source files, each is compiled +# separately, in a well-defined order. The resulting object files might +# be optionally linked and optionally executed. Grouping is indicated by +# naming files '*_[a-z].[CH]' + +# { dg-module-cmi "[!]module-name" } # an interface file is (not) expected +# { dg-module-do [link|run] [xfail] [options] } # link [and run] + +load_lib g++-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CXXFLAGS +if ![info exists DEFAULT_CXXFLAGS] then { + set DEFAULT_CXXFLAGS " -pedantic-errors -Wno-long-long" +} +set DEFAULT_MODFLAGS $DEFAULT_CXXFLAGS +set MOD_STD_LIST { 17 2a } + +setenv CXX_MODULE_PATH "$srcdir/$subdir" +dg-init + +global module_do +global module_cmis +global module_headers + +set DEFAULT_REPO "gcm.cache" + +# Register the module name this produces. +# dg-module-cmi !?=?NAME WHEN? +# dg-module-cmi !?{} - header unit +proc dg-module-cmi { args } { + if { [llength $args] > 3 } { + error "[lindex $args 0]: too many arguments" + return + } + set spec [lindex $args 1] + if { [llength $args] > 2 } { + set when [lindex $args 2] + } else { + set when {} + } + + if { [string index $spec 0] == "!" } { + set name [string range $spec 1 end] + set not 1 + } else { + set name $spec + set not 0 + } + + if { [string index $name 0] == "=" } { + set cmi [string range $name 1 end] + } else { + if { $name == "" } { + # get the source file name. ick! + upvar prog srcname + set cmi "$srcname.gcm" + if { [string index $cmi 0] == "/" } { + set cmi [string range $cmi 1 end] + } else { + set cmi ",/$cmi" + } + set path [file split $cmi] + # subst /../ -> /,,/ + # sadly tcl 8.5 does not have lmap + set rplac {} + foreach elt $path {lappend rplac [expr {$elt == ".." ? ",," : $elt}]} + set cmi [file join {*}$rplac] + } else { + set cmi "[regsub : $name -].gcm" + } + global DEFAULT_REPO + set cmi "$DEFAULT_REPO/$cmi" + } + + # delete file, so we don't get confused by a stale one. + file_on_host delete "$cmi" + + global module_cmis + lappend module_cmis [list $spec $when $not $cmi] +} + +# check the expected module files exist (or not) +# return list to delete +proc module_cmi_p { src ifs } { + set res {} + foreach if_arg $ifs { + set spec [lindex $if_arg 0] + set when [lindex $if_arg 1] + if { $when != "" } { + switch [dg-process-target $when] { + "S" { } + "N" { continue } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + set not [lindex $if_arg 2] + set cmi [lindex $if_arg 3] + if { $not != [file_on_host exists $cmi] } { + pass "$src module-cmi $spec ($cmi)" + } else { + fail "$src module-cmi $spec ($cmi)" + set not [expr ! $not ] + } + if { ! $not } { + lappend res $cmi + } + } + return $res +} + +# Append required header unit names to module_headers var +proc dg-module-headers { args } { + if { [llength $args] != 3 } { + error "[lindex $args 0]: wrong number of arguments" + return + } +} + +proc do_module_headers { srcdir subdir std flags} { + global module_headers + foreach header $module_headers { + set kind [lindex $header 0] + set hdr [lindex $header 1] + verbose "Header $hdr $std" 1 + switch $kind { + test { + global module_cmis + set module_cmis {} + dg-test -keep-output $srcdir/$subdir/$hdr "$std" $flags + global mod_files + lappend mod_files [module_cmi_p $subdir/$hdr $module_cmis] + } + system - + user { + # FIXME + } + default { + error "$kind unknown header" + } + } + } +} + +# link and maybe run a set of object files +# dg-module-do WHAT WHEN +proc dg-module-do { args } { + if { [llength $args] > 3 } { + error "[lindex $args 0]: too many arguments" + return + } + + set do_what [lindex $args 1] + set expected "P" + if { [llength $args] > 2 } { + set expected [dg-process-target [lindex $args 2]] + } + + global module_do + set module_do [list $do_what $expected] +} + +proc module_do_it { do_what testcase std asm_list } { + global tool + + set run 0 + switch [lindex $do_what 0] { + "compile" { return 1 } + "link" { } + "run" { set run 1 } + default { error "unknown module-do action [lindex $do_what 0]" } + } + + set xfail {} + switch [lindex $do_what 1] { + "S" { } + "N" { return 1 } + "F" { set xfail {setup_xfail "*-*-*"} } + "P" { } + } + + set ok 1 + # make sure all asms are around + foreach asm $asm_list { + if { ! [file_on_host exists $asm] } { + set ok 0 + } + } + + set options { } + if { $std != "" } { + lappend options "additional_flags=$std" + } + if { [llength $do_what] > 3 } { + lappend options "additional_flags=[lindex $do_what 3]" + } + + set execname "./[file tail $testcase].exe" + + # link it + verbose "Linking $asm_list" 1 + if { !$ok } { + unresolved "$testcase link" + } else { + set out [${tool}_target_compile $asm_list \ + $execname executable $options] + eval $xfail + if { $out == "" } { + pass "$testcase link" + } else { + fail "$testcase link" + set ok 0 + } + } + + # run it? + if { !$run } { + } elseif { !$ok } { + unresolved "$testcase execute" + } else { + set out [${tool}_load $execname "" ""] + set status [lindex $out 0] + eval $xfail + $status "$testcase execute" + if { $status != "pass" } { + set $ok 0 + } + } + + if { $ok } { + file_on_host delete $execname + } + + return $ok +} + +# delete the specified set of module files +proc cleanup_module_files { files } { + foreach file $files { + file_on_host delete $file + } +} + +global testdir +set testdir $srcdir/$subdir +proc srcdir {} { + global testdir + return $testdir +} + +# Return set of std options to iterate over, taken from g++-dg.exp & compat.exp +proc module-init { src } { + set tmp [dg-get-options $src] + set option_list {} + global module_headers + set module_headers {} + set have_std 0 + set std_prefix "-std=c++" + + foreach op $tmp { + switch [lindex $op 0] { + "dg-options" { + set std_prefix "-std=gnu++" + if { [string match "*-std=*" [lindex $op 2]] } { + set have_std 1 + } + } + "dg-additional-options" { + if { [string match "*-std=*" [lindex $op 2]] } { + set have_std 1 + } + } + "dg-module-headers" { + set kind [lindex $op 2] + foreach header [lindex $op 3] { + lappend module_headers [list $kind $header] + } + } + } + } + + if { !$have_std } { + global MOD_STD_LIST + foreach x $MOD_STD_LIST { + lappend option_list "${std_prefix}$x" + } + } else { + lappend option_list "" + } + + return $option_list +} + +# not grouped tests, sadly tcl doesn't have negated glob +foreach test [prune [lsort [find $srcdir/$subdir {*.[CH]}]] \ + "$srcdir/$subdir/*_?.\[CH\]"] { + if [runtest_file_p $runtests $test] { + set nshort [file tail [file dirname $test]]/[file tail $test] + + set std_list [module-init $test] + foreach std $std_list { + do_module_headers $srcdir $subdir $std $DEFAULT_MODFLAGS + set module_cmis {} + verbose "Testing $nshort $std" 1 + dg-test $test "$std" $DEFAULT_MODFLAGS + set testcase [string range $test [string length "$srcdir/"] end] + cleanup_module_files [module_cmi_p $testcase $module_cmis] + } + } +} + +# grouped tests +foreach src [lsort [find $srcdir/$subdir {*_a.[CH}]] { + # use the FOO_a.C name as the parallelization key + if [runtest_file_p $runtests $src] { + set tests [lsort [find [file dirname $src] \ + [regsub {_a.[CH]$} [file tail $src] {_[a-z].[CH]}]]] + + set std_list [module-init $src] + foreach std $std_list { + set mod_files {} + global module_do + set module_do {"compile" "P"} + set asm_list {} + do_module_headers $srcdir $subdir $std $DEFAULT_MODFLAGS + foreach test $tests { + if { [lindex $module_do 1] != "N" } { + set module_cmis {} + set nshort [file tail [file dirname $test]]/[file tail $test] + verbose "Testing $nshort $std" 1 + if { [file extension $test] == ".C" } { + lappend asm_list [file rootname [file tail $test]].s + } + dg-test -keep-output $test "$std" $DEFAULT_MODFLAGS + set testcase [string range $test [string length "$srcdir/"] end] + lappend mod_files [module_cmi_p $testcase $module_cmis] + } + } + set ok 1 + set testcase [regsub {_a.[CH]} $src {}] + set testcase \ + [string range $testcase [string length "$srcdir/"] end] + set ok [module_do_it $module_do $testcase $std $asm_list] + if { $ok } { + foreach asm $asm_list { + file_on_host delete $asm + } + cleanup_module_files $mod_files + } + } + } +} + +dg-finish