Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2010-2013 Joel Rosdahl
3 : : *
4 : : * This program is free software; you can redistribute it and/or modify it
5 : : * under the terms of the GNU General Public License as published by the Free
6 : : * Software Foundation; either version 3 of the License, or (at your option)
7 : : * any later version.
8 : : *
9 : : * This program is distributed in the hope that it will be useful, but WITHOUT
10 : : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 : : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 : : * more details.
13 : : *
14 : : * You should have received a copy of the GNU General Public License along with
15 : : * this program; if not, write to the Free Software Foundation, Inc., 51
16 : : * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 : : */
18 : :
19 : : /*
20 : : * This file contains tests for the processing of compiler arguments.
21 : : */
22 : :
23 : : #include "ccache.h"
24 : : #include "conf.h"
25 : : #include "test/framework.h"
26 : : #include "test/util.h"
27 : :
28 : : extern struct conf *conf;
29 : :
30 : 1 : TEST_SUITE(argument_processing)
31 : :
32 [ + - ]: 1 : TEST(dash_E_should_result_in_called_for_preprocessing)
33 : : {
34 : 1 : struct args *orig = args_init_from_string("cc -c foo.c -E");
35 : : struct args *preprocessed, *compiler;
36 : :
37 : 1 : create_file("foo.c", "");
38 [ + - ]: 1 : CHECK(!cc_process_args(orig, &preprocessed, &compiler));
39 [ - + ]: 1 : CHECK_INT_EQ(1, stats_get_pending(STATS_PREPROCESSING));
40 : :
41 : 1 : args_free(orig);
42 : : }
43 : :
44 [ + - ]: 1 : TEST(dash_M_should_be_unsupported)
45 : : {
46 : 1 : struct args *orig = args_init_from_string("cc -c foo.c -M");
47 : : struct args *preprocessed, *compiler;
48 : :
49 : 1 : create_file("foo.c", "");
50 [ + - ]: 1 : CHECK(!cc_process_args(orig, &preprocessed, &compiler));
51 [ - + ]: 1 : CHECK_INT_EQ(1, stats_get_pending(STATS_UNSUPPORTED));
52 : :
53 : 1 : args_free(orig);
54 : : }
55 : :
56 [ + - ]: 1 : TEST(dependency_flags_should_only_be_sent_to_the_preprocessor)
57 : : {
58 : : #define CMD \
59 : : "cc -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 -MQ mq1 -MQ mq2" \
60 : : " -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
61 : 1 : struct args *orig = args_init_from_string(CMD " -c foo.c -o foo.o");
62 : 1 : struct args *exp_cpp = args_init_from_string(CMD);
63 : : #undef CMD
64 : 1 : struct args *exp_cc = args_init_from_string("cc -c");
65 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
66 : 1 : create_file("foo.c", "");
67 : :
68 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
69 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
70 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
71 : :
72 : 1 : args_free(orig);
73 : : }
74 : :
75 [ + - ]: 1 : TEST(preprocessor_only_flags_should_only_be_sent_to_the_preprocessor)
76 : : {
77 : : #define CMD \
78 : : "cc -I. -idirafter . -iframework. -imacros . -imultilib ." \
79 : : " -include test.h -include-pch test.pch -iprefix . -iquote ." \
80 : : " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ." \
81 : : " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory" \
82 : : " -fno-working-directory -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 "\
83 : : " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
84 : 1 : struct args *orig = args_init_from_string(CMD " -c foo.c -o foo.o");
85 : 1 : struct args *exp_cpp = args_init_from_string(CMD);
86 : : #undef CMD
87 : 1 : struct args *exp_cc = args_init_from_string("cc -c");
88 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
89 : 1 : create_file("foo.c", "");
90 : :
91 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
92 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
93 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
94 : :
95 : 1 : args_free(orig);
96 : : }
97 : :
98 [ + - ]: 1 : TEST(dependency_flags_that_take_an_argument_should_not_require_space_delimiter)
99 : : {
100 : 1 : struct args *orig = args_init_from_string(
101 : 1 : "cc -c -MMD -MFfoo.d -MT mt -MTmt -MQmq foo.c -o foo.o");
102 : 1 : struct args *exp_cpp = args_init_from_string(
103 : 1 : "cc -MMD -MFfoo.d -MT mt -MTmt -MQmq");
104 : 1 : struct args *exp_cc = args_init_from_string("cc -c");
105 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
106 : 1 : create_file("foo.c", "");
107 : :
108 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
109 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
110 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
111 : :
112 : 1 : args_free(orig);
113 : : }
114 : :
115 [ + - ]: 1 : TEST(sysroot_should_be_rewritten_if_basedir_is_used)
116 : : {
117 : : extern char *current_working_dir;
118 : : char *arg_string;
119 : : struct args *orig;
120 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
121 : :
122 : 1 : create_file("foo.c", "");
123 : 1 : free(conf->base_dir);
124 : 1 : conf->base_dir = x_strdup("/");
125 : 1 : current_working_dir = get_cwd();
126 : 1 : arg_string = format("cc --sysroot=%s/foo -c foo.c", current_working_dir);
127 : 1 : orig = args_init_from_string(arg_string);
128 : :
129 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
130 [ + - ]: 1 : CHECK(str_startswith(act_cpp->argv[1], "--sysroot=./foo"));
131 : :
132 : 1 : args_free(orig);
133 : 1 : args_free(act_cpp);
134 : 1 : args_free(act_cc);
135 : : }
136 : :
137 [ + - ]: 1 : TEST(MF_flag_with_immediate_argument_should_work_as_last_argument)
138 : : {
139 : 1 : struct args *orig = args_init_from_string(
140 : 1 : "cc -c foo.c -o foo.o -MMD -MT bar -MFfoo.d");
141 : 1 : struct args *exp_cpp = args_init_from_string(
142 : 1 : "cc -MMD -MT bar -MFfoo.d");
143 : 1 : struct args *exp_cc = args_init_from_string("cc -c");
144 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
145 : 1 : create_file("foo.c", "");
146 : :
147 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
148 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
149 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
150 : :
151 : 1 : args_free(orig);
152 : : }
153 : :
154 [ + - ]: 1 : TEST(MT_flag_with_immediate_argument_should_work_as_last_argument)
155 : : {
156 : 1 : struct args *orig = args_init_from_string(
157 : 1 : "cc -c foo.c -o foo.o -MMD -MFfoo.d -MT foo -MTbar");
158 : 1 : struct args *exp_cpp = args_init_from_string(
159 : 1 : "cc -MMD -MFfoo.d -MT foo -MTbar");
160 : 1 : struct args *exp_cc = args_init_from_string("cc -c");
161 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
162 : 1 : create_file("foo.c", "");
163 : :
164 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
165 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
166 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
167 : :
168 : 1 : args_free(orig);
169 : : }
170 : :
171 [ + - ]: 1 : TEST(MQ_flag_with_immediate_argument_should_work_as_last_argument)
172 : : {
173 : 1 : struct args *orig = args_init_from_string(
174 : 1 : "cc -c foo.c -o foo.o -MMD -MFfoo.d -MQ foo -MQbar");
175 : 1 : struct args *exp_cpp = args_init_from_string(
176 : 1 : "cc -MMD -MFfoo.d -MQ foo -MQbar");
177 : 1 : struct args *exp_cc = args_init_from_string("cc -c");
178 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
179 : 1 : create_file("foo.c", "");
180 : :
181 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
182 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
183 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
184 : :
185 : 1 : args_free(orig);
186 : : }
187 : :
188 [ + - ]: 1 : TEST(MQ_flag_without_immediate_argument_should_not_add_MQobj)
189 : : {
190 : 1 : struct args *orig = args_init_from_string(
191 : 1 : "gcc -c -MD -MP -MFfoo.d -MQ foo.d foo.c");
192 : 1 : struct args *exp_cpp = args_init_from_string(
193 : 1 : "gcc -MD -MP -MFfoo.d -MQ foo.d");
194 : 1 : struct args *exp_cc = args_init_from_string("gcc -c");
195 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
196 : 1 : create_file("foo.c", "");
197 : :
198 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
199 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
200 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
201 : :
202 : 1 : args_free(orig);
203 : : }
204 : :
205 [ + - ]: 1 : TEST(MT_flag_without_immediate_argument_should_not_add_MTobj)
206 : : {
207 : 1 : struct args *orig = args_init_from_string(
208 : 1 : "gcc -c -MD -MP -MFfoo.d -MT foo.d foo.c");
209 : 1 : struct args *exp_cpp = args_init_from_string(
210 : 1 : "gcc -MD -MP -MFfoo.d -MT foo.d");
211 : 1 : struct args *exp_cc = args_init_from_string("gcc -c");
212 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
213 : 1 : create_file("foo.c", "");
214 : :
215 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
216 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
217 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
218 : :
219 : 1 : args_free(orig);
220 : : }
221 : :
222 [ + - ]: 1 : TEST(MQ_flag_with_immediate_argument_should_not_add_MQobj)
223 : : {
224 : 1 : struct args *orig = args_init_from_string(
225 : 1 : "gcc -c -MD -MP -MFfoo.d -MQfoo.d foo.c");
226 : 1 : struct args *exp_cpp = args_init_from_string(
227 : 1 : "gcc -MD -MP -MFfoo.d -MQfoo.d");
228 : 1 : struct args *exp_cc = args_init_from_string("gcc -c");
229 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
230 : 1 : create_file("foo.c", "");
231 : :
232 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
233 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
234 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
235 : :
236 : 1 : args_free(orig);
237 : : }
238 : :
239 [ + - ]: 1 : TEST(MT_flag_with_immediate_argument_should_not_add_MQobj)
240 : : {
241 : 1 : struct args *orig = args_init_from_string(
242 : 1 : "gcc -c -MD -MP -MFfoo.d -MTfoo.d foo.c");
243 : 1 : struct args *exp_cpp = args_init_from_string(
244 : 1 : "gcc -MD -MP -MFfoo.d -MTfoo.d");
245 : 1 : struct args *exp_cc = args_init_from_string("gcc -c");
246 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
247 : 1 : create_file("foo.c", "");
248 : :
249 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
250 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
251 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
252 : :
253 : 1 : args_free(orig);
254 : : }
255 : :
256 [ + - ]: 1 : TEST(fprofile_flag_with_existing_dir_should_be_rewritten_to_real_path)
257 : : {
258 : 1 : struct args *orig = args_init_from_string(
259 : 1 : "gcc -c -fprofile-generate=some/dir foo.c");
260 : 1 : struct args *exp_cpp = args_init_from_string("gcc");
261 : 1 : struct args *exp_cc = args_init_from_string("gcc");
262 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
263 : : char *s;
264 : :
265 : 1 : create_file("foo.c", "");
266 : 1 : mkdir("some", 0777);
267 : 1 : mkdir("some/dir", 0777);
268 : 1 : s = format("-fprofile-generate=%s", x_realpath("some/dir"));
269 : 1 : args_add(exp_cpp, s);
270 : 1 : args_add(exp_cc, s);
271 : 1 : args_add(exp_cc, "-c");
272 : 1 : free(s);
273 : :
274 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
275 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
276 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
277 : :
278 : 1 : args_free(orig);
279 : : }
280 : :
281 [ + - ]: 1 : TEST(fprofile_flag_with_nonexisting_dir_not_be_rewritten)
282 : : {
283 : 1 : struct args *orig = args_init_from_string(
284 : 1 : "gcc -c -fprofile-generate=some/dir foo.c");
285 : 1 : struct args *exp_cpp = args_init_from_string(
286 : 1 : "gcc -fprofile-generate=some/dir");
287 : 1 : struct args *exp_cc = args_init_from_string(
288 : 1 : "gcc -fprofile-generate=some/dir -c");
289 : 1 : struct args *act_cpp = NULL, *act_cc = NULL;
290 : :
291 : 1 : create_file("foo.c", "");
292 : :
293 [ + - ]: 1 : CHECK(cc_process_args(orig, &act_cpp, &act_cc));
294 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
295 [ - + ]: 1 : CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
296 : :
297 : 1 : args_free(orig);
298 : : }
299 : :
300 : 1 : TEST_SUITE_END
|