社団法人 電子情報通信学会
THE INSTITUTE OF ELECTRONICS,INFORMATION AND COMMUNICATION ENGINEERS

信学技報 VLD2006-95/CPSY2006-66/RECONF2006-66 (2007-01)

TECHNICAL REPORT OF IEICE.

C コンパイラ用テストスイートおよびその生成ツール testgen内山裕貴†

引地信之††

石浦菜岐佐†

永松 祐二†††† 関西学院大学 理工学部 〒 669–1337 兵庫県三田市学園 2-1†† SRA 〒 171–8513 東京都豊島区南池袋 2-32-8††† 関西学院大学 (現在 日本総合研究所)
E-mail: †{uchiyama-y,ishiura}@ksc.kwansei.ac.jp, ††hikichi@sra.co.jp
コンパイラのテストは，一般にテストスイート (コンパイラの入力となるプログラムの集合) を用いて行あらましう．コンパイラ用テストスイートには類似したコードが多く含まれる傾向があり，プログラムの保守性という点からは必ずしも望ましくない．また，テストに用いるコンパイラやシミュレータの変更やテスト項目の指定などに多くの手作業が必要になることがある．本稿ではこれらの問題を解決する一手法としてテストプログラムの元となる「テンプレートファイル」と設定ファイルからテストスイートを生成する手法を提案する. 本手法を既存のテストスイートに適用した結果，テストプログラムの記述量を約 60%に削減することができた．
キーワード

C 言語, コンパイラ, テストスイート, gcc

Test Suite of C Compilers and Its Generating Tool “testgen”
Yuki UCHIYAMA† , Nobuyuki HIKICHI†† , Nagisa ISHIURA† , and Yuji NAGAMATSU†††† Kwansei Gakuin University, Gakuen 2-1, Sanda, Hyogo, 669–1337 Japan†† SRA, Minami Ikebukuro 2-32-8, Tosima-ku, Tokyo, 171–8513 Japan††† Kwansei Gakuin University (now with the Japan Research Institute)E-mail: †{uchiyama-y,ishiura}@ksc.kwansei.ac.jp, ††hikichi@sra.co.jp
Abstract The testing of compilers is usually done using a test suite, or a collection of programs fed into the compilers. The test suite for compilers often includes many similar codes, which is not desiarable from the viewpointof the program maintainability. It sometimes takes manual editing of many files to switch compilers and simulatorsor to select specific test sets. As an approach to solve those problems, we propose in this article a method ofgenerating test suites from “template files,” which are reduced description of the test programs, and a configaration
file. We demonstrate that the total number of the lines for describing an exisiting test suite is reduced to 60% by
the proposed method.
Key words C language, compiler, test suite, gcc

1. は じ め にプログラム，その集合をテストスイートと呼ぶ．
コンパイラのテストスイートには，類似したプログラムが多組み込みシステムに課せられる性能，電力，コスト等の厳しく含まれる傾向がある．例えば，変数への代入処理が正しく行い制約を満たす一つのアプローチとして，近年 ASIP (Appli-えるかをテストするプログラムでは，同様の処理を異なる型やcation Specific Instruction Processor) 等ターゲットに特化し異なる記憶クラスの変数に適用するため，変数宣言部分のみがたプロセッサを設計する機会が増えている．これに伴い，新し異なる類似したテストコードが多数存在することになる．このいプロセッサに対するコンパイラを開発する機会も増えており，ように重複の多いプログラムは，変更を行うときの影響が複数そのテストが重要な課題となる．

箇所に及ぶため，保守性の観点からは望ましくない. また，テコンパイラのテストは，入力となるプログラムの集合を準備ストを行うコンパイラやシミュレータの変更，テストスクリプし，そのプログラムのコンパイルがエラーなく行えるか，コントの動作の変更，テストスイートの一部のみを実行する指定なパイルされたプログラムが期待通りの動作をするかを確認する

どを行うために，幾つものファイルを変更しなければならない

ことにより行う．コンパイラの入力となるプログラムをテストケースが生じる．

—1—

本稿では，これらの問題を解決するための一手法として，テストプログラムの元となる「テンプレートファイル」と設定ファイルからテストスイートと必要なテストスクリプトを生成する手法を提案する．この手法により，テストプログラム記述量の減少による保守性の向上，設定ファイルによる環境カスタマイズの容易化，部分的なテストスイートの生成を実現する.
本手法を SRA で開発された C コンパイラ用テストスイート(以下 SRA テストスイート) に適用し結果，テストプログラムの記述量を約 60%に削減でき，異なった環境で使用する際の設定変更が容易に行えるようになった．

2. C コンパイラ用テストスイート
C コンパイラのテストスイートは, 一般に C 言語で書かれたテストプログラムの集合から成るが，テスト実行や結果の解析

図 1 SRA テストスイートのディレクトリ構成を行うスクリプトを含めてテストスイートと呼ぶこともある．
テストプログラムの数はテストスイートによって異なるが，数千から数万を超えるものまであり，非常に大規模になる．

2. 1 既存のテストスイート(1) GCC テストスイート （注 1）
GCC (GNU Compiler Collection) に付属のテストスイート
は，GCC のテストを主な目的として作成されたテストスイー
トである. テストプログラムのファイル数は約 2,500 個で，総行数は 23,000 行である．テストのフレームワークに dejagnu（注 2）

を用いている．

テストプログラムは C 言語の仕様として標準で定められている言語仕様のテストに加え，GCC 独自の言語拡張のテストも含む．そのため，GCC 以外のコンパイラに適用しようとすると，多くの修正が必要となる．
また，テスト結果の出力に出力関数を用いており，ライブラリの存在を前提としている．しかしコンパイラ開発時にはライブラリが利用できない場合が多く (ライブラリが完全にコンパイルできない等の理由による)，その場合には何らかの出力機能を別途作成する必要がある．

(2) quest （注 3）quest は，関数呼び出しの引数渡しのテスト用の C プログラ
ムを自動生成するツールである．

quest を実行すると引数の型と個数がランダムな関数，およびその関数を呼び出す関数が記述されたテストプログラムが生成される．生成された関数の引数は基本型，ポインタ，配列，構造体，およびこれらの複雑な組み合わせを含む．quest はテスト項目を関数呼び出し時の引数渡しに絞ってコンパイラの完成度を高めることに適しているが，その他の構文はほとんどカバーしない．

(3) SRA テストスイート
SRA テストスイートは多くのコンパイラへの適用，およびコンパイラの開発段階での適用を目的とした，汎用性の高いテストスイートである．テストスイートのファイル数は約 9,300個，テストプログラムの総行数は約 48 万行である．

GCC テストスイートが対象となるコンパイラを限定しているのに対し，SRA テストスイートは C 言語の標準的な機能のテストに重点を置いている．
テストスイートは基本的な機能のテストを行う小さなプログ
ラムを多数含んでおり，コンパイラ開発時でのテストでエラー原因を特定しやすい．また，テストプログラムはファイル名で浮動小数点型，整数型の区別をできるようになっており，問題の特定や一部の型のみのテストが行いやすい．
テスト結果の出力はマクロ定義されており，ライブラリが利用できない場合には，例えばメモリの特定番地へのデータの書き込み等に変更できる．そのため，コンパイラ開発の初期段階でライブラリが未完成であっても利用が可能である．
図??に SRA テストスイートのディレクトリ構成を示す. SRA
テストスイートは C 言語のテストプログラム集合，テスト実行スクリプト，ライブラリ等から構成される. フレームワークにはGCC テストスイートと同様に dejagnu を用いており，dejagnuのコマンドとオプションが記述された “RUNTEST” スクリプ
トを実行することによりテストを行う．RUNTEST は各ディレクトリに配置された compile.exp (コンパイルのテストスクリプト), execute.exp (実行のテストスクリプト) を次々に呼び出すことによりコンパイラのテストを行う．

2. 2 SRA テストスイートの問題点
SRA テストスイートのテストプログラムには，差異の少ないテストプログラムが数多く含まれている. 図??にその一例を示す．これは変数への代入が正しく行われているかをテストするプログラムであるが，(1) と (2) を比較すると変数宣言が異なっているだけで，それ以外の部分は共通である．もしテストプログラムに対する変更が必要になった場合には，同様の変更を多数の箇所に対して行わなければならない．
また，テスト環境のカスタマイズを行うには多くのファイル（注 1）：http://gcc.gnu.org/（注 2）：http://www.gnu.org/software/dejagnu/（注 3）：http://www.st.cs.uni-sb.de/ lindig/src/quest/を修正する必要が生じる. 例えば，クロス開発環境で，実行にシミュレータを用いる場合，各ディレクトリに存在する実行ス—2—

#ifdef SYSDEP_H#include "sysdep.h"#endif#include "stnd.h"main(){
int Var;itest = NO;
Var = OK;
itest = Var;if(itest==OK)printok();else
printno();return (0);}#ifdef SYSDEP_H#include "sysdep.h"#endif#include "stnd.h"main(){
char Var;
itest = NO;
Var = OK;
ictest = Var;if(itest==OK)printok();else
printno();return (0);}(1) gcc.1-1/t000.c
図2(2) gcc.1-1/t012.c

共通部分の多いテストプログラムの例

1 @comment
2 変数の代入のテスト
3 @end_comment
4
5 @multiline HEADER
6 #ifdef SYSDEP_H
7 #include "sysdep.h"
8 #endif
9 #include "stnd.h"
10 @end_multiline HEADER
1112 @for VARIABLE ’int’ ’short’ ’char’13 @for TYPE ’’ ’static’ ’register’14 @file t???_$MODIFIER_$VARIABLE.c
15
16 $HEADER
17 main(){図3

テストスイート生成の流れ

クリプトである execute.exp をすべて修正しなければならない．

18$MODIFIER $TYPE Variable;

19

itest = NO;

20

Variable = OK;

21

itest = Variable;22

if(itest == OK) printok();

23elseprintno();24 }3. 提案するテストスイート生成の手法

25
26 @end_file

本稿では 2.2 節で述べた問題点を解決する一手法として，テストプログラムの元となる「テンプレートファイル」と設定ファイルからテストスイートを生成する手法を提案する. この手法は，•

テストプログラム記述量の減少による保守性の向上•

設定ファイルによる環境カスタマイズの容易化•

部分的なテストスイートの生成を目的とする.

27 @end_for VARIABLE
28 @end_for MODIFIER
29
30 @run compile.exp execute.exp
図4

テンプレートファイルの例

しており, 15 行目の $HEAD は 5〜7 行目の内容で置換され図??に提案するテストスイート自動生成の流れを示す．テス

る. 12, 13〜27, 28 行目の@for から@end for は，その間に記ト生成ツールはテンプレートファイルと設定ファイルを入力と述されたコードを, 変数の置換を行いながら繰り返し生成する.

し，テストプログラム集合，およびテストスクリプトを生成す@for はネストが可能であり, この例では 9 通りの異なったプロる. テンプレートファイルは，一つのテストディレクトリに存グラムが生成される. 14〜26 行目の @file から @end file で囲在する全てのテストプログラムやスクリプトファイルを一つにまれた部分が一つのテストプログラムに対応する. @file の後まとめて記述したファイルである. 設定ファイルには環境情報にはファイル名を記述し, “??” はテストプログラムの通し番号を記述し，その変更により生成されるテストプログラムや実行で置換される．

スクリプトを容易に変更できるようにする．

図??はファイル名が t001 static int.c で生成されたテストプ

3. 1 テンプレートファイル

ログラムである．プログラムは図??の 16 行目〜24 行目に相当

テンプレートファイルは，複数のテストプログラム中の重複し，13 行目の$HEADER，15 行目の$MODIFIER と$TYPE

部分のくくり出しと繰り返し構文の適用により，記述量を削減してテストスイートの保守性の向上を図るものである．

がそれぞれ置換されている．

3. 2 設定ファイル

図??にテンプレートファイルの例を示す．1〜3 行目はコメ

図 6 に native コンパイラ (gcc) をテストするめの設定ファイントであり, 生成されるテストプログラムには影響しない. 5〜

ルの例を示す．1 行目から 3 行目は順に，テストを行うコンパ

10 行は変数の定義である. ここでは HEAD という変数を定義

イラ，ターゲット，実行時のシミュレータ (空白の場合は生成—3—イート，ログ等を出力するディレクトリを指定する.

#ifdef SYSDEP_H

図 7 はクロスコンパイラをテストするための設定ファイルの#include "sysdep.h"#endif例である．この設定では，コンパイラに m32r-unknown-elf-gcc，ターゲットに m32r-gcc, シミュレータに m32r-unknown-elf-run#include "stnd.h"を指定している．

main(){

一つの設定ファイルに必要な情報をすべて記述することによstatic int Variable;

り，テストスイートのカスタマイズ性を向上できる．

itest = NO;

3. 3 部分的なテストスイートの生成

Variable = OK;

テストスイート生成時に，入力となるテンプレートファイル

itest = Variable;を選択することにより，部分的なテストスイート生成を可能とrefer(itest);

する．また，生成時のオプションとして整数型のみを含むテス}

ト，浮動小数点型のみを含むテストを-f, -i オプションにより指refer(int itest){定できるようにする．

if(itest == OK) printok();
elseprintno();}4. testgen の実装と利用例
以上の提案手法に基づくテスト生成スクリプト “testgen” を

図5生成されるテストプログラム

Perl 5 で実装した．testgen は Linux Fedora Core 4, Cygwin
1.5, Max OS X, Debian GNU Linux 上の Perl 5.8.7 以上で動1 CC:gcc
2 TARGET:gcc

作する．
次に，testgen を SRA テストスイートに適用した．SRA テ

3 SIMULATOR_NAME:

ストスイートと同じテストスイートを生成するテンプレート

4 TOOL:gcc

ファイル，および設定ファイルを作成した．テンプレートファ

5 LIBS:

イルから正しくテストスイートが生成されることは，生成され6 LDFLAGS:

た全テストプログラムを “diff” コマンドにより比較し，テキス

7 FILSET:FILSET

ト的に異なるものについては目視での確認をすることにより確

8 OBJ:.

かめた．

9 LOG:log
10 TESTDIR:testsuite
図6

設定ファイルの記述例 (native 環境)

表??は SRA テストスイートのテストプログラムの行数と，同じテストプログラムを生成するテンプレート記述の行数を比較たものである．全体としては行数が約 60%に減少した．
表1

1 CC:m32r-unknown-elf-gcc

ディレクトリ名

2 TARGET:m32r-gcc

記述量の比較
元のテスト テンプレート

スイート (行)

記述 (行)965

3 SIMULATOR_NAME:m32r-unknown-elf-run

gcc.1-1

1,822

4 TOOL:gcc

gcc.2-1-01

3,351

999

5 LIBS:gcc.3-1

6,080

5,623

6 LDFLAGS:

gcc.4-1

2,364

2,149

gcc.5-1

452

310

2,152

2,259

485,232

284,619

7 FILSET:FILSET
8 OBJ:.

gcc.6-1-01
全体

9 LOG:log
10 TESTDIR:m32r-testsuite
図7

設定ファイルの記述例 (m32r クロス環境)

SRA テストスイートは，ファイル名のマッチングで整数型のテストプログラムのみを抽出できるようになっているが，一部の整数型のテストプログラムのヘッダ中に浮動小数点型変数されたコードが実行可能ファイルとして実行される) を指定しの宣言が含まれるという誤りが発見された．この問題の修正をている. 4 行目はテストを行うディレクトリの名前を指定してテストスイートに対して直接行うには約 3,000 個のプログラムおり，ここに定義された文字列で始まるディレクトリをテストファイルの修正が必要となるが，テンプレートファイルに対し対象とする．5 行目から 7 行目ではテスト実行時のオプションて修正を行えば 100 ファイルで済んだ．このことからも，テスやライブラリ等の指定を行う. 8 行目から 10 行目ではテストス

トスイート生成の枠組みは，テストスイートの保守性の向上に有用であると考える．

—4—

生成されたテストスイートにより，コンパイラのテストが正常に行えることを下記の環境で確認した．

•

Mac OS X 10.3.9/GCC 3.3.4•

Cygwin on Win2k/GCC 3.3.4•

Fedora Core 4/GCC 4.0.0•

Debian GNU Linux/GCC 3.3.5生成されたテストを全て実行すると native gcc (3.4.6), Fe-dora Core 4 Linux (Pentium4 2GHz, 512MB Mem) 環境で1 時間弱の時間を要する．また，native gcc (3.4.4), Cygwin(1.5)/WindowsXP SP2 (PentiumM 1.5Ghz, 1024MB Mem)
環境は 3 時間弱が必要となる．

5. ま と め
本研究ではテンプレート記述からテストスイートを自動生成する手法の提案と，その SRA テストスイートへの適用について述べた.

testgen (テストスイートを含む) は
http://ist.ksc.kwansei.ac.jp/~ishiura/testgen/
で公開している．
このテストスイートを改良すべき点としては下記が挙げられる．テストスイート生成によりこれらの点が解決できないか，今後検討を進める予定である．

(1) ほとんどのテストプログラムで使っている値は 0, 1 だけなので，境界値を含む多くの値によるテストの追加が望まれる．
境界値はコンパイラやターゲットプロセッサ等によって異なるので，設定ファイルとテストスイート生成の組み合わせが有効と考える．

(2) このテストスイートを全て実行した場合に要する時間は開発時に何度もテストを行うことを考えると大幅に短縮することが望まれる．複数の機能のテストを一つのプログラムにまとめることができればテストの時間が短縮できるので，テストスイート生成によるその実現を検討したい．

(3) 現在のテストプログラムはすべて K&R C で書かれているが，ANSI C や C99 に対応する必要がある．この際にもテストスイート生成での解決が有効と考える．
謝辞

本研究は, IPA 2004 年度オープンソースソフトウェア活用基盤整備事業のプロジェクト「C コンパイラ向けテストスイート生成ツールの開発」に採択されたものである．
本研究に際し，多くの助言や協力を頂いた関西学院大学の森
本剛徳氏，粟津裕亘氏をはじめとする石浦研究室の諸氏に感謝します．
文

献[1] Don Libes: ”Exploring Expect”, O’REILLY, (1995).
[2] B.W. カーニハン/D.M. リッチー著 石田晴久訳: ”プログラミン
グ言語 C 第 2 版 ANSI 規格準拠”, 共立出版株式会社, (1989).

—5—