Fix for bug 8118.
Some (ie clang) give warnings for unused arguments. Arguments that are only
used during the preprocessing phase will cause warnings during the
compilation phase.
bool dependency_filename_specified = false;
/* is the dependency makefile target name specified with -MT or -MQ? */
bool dependency_target_specified = false;
- struct args *expanded_args, *stripped_args, *dep_args;
+ struct args *expanded_args, *stripped_args, *dep_args, *cpp_args;
int argc;
char **argv;
bool result = true;
expanded_args = args_copy(args);
stripped_args = args_init(0, NULL);
dep_args = args_init(0, NULL);
+ cpp_args = args_init(0, NULL);
argc = expanded_args->argc;
argv = expanded_args->argv;
* is that paths in the standard error output produced by the
* compiler will be normalized.
*/
+
if (compopt_takes_path(argv[i])) {
char *relpath;
char *pch_file = NULL;
goto out;
}
- args_add(stripped_args, argv[i]);
+ /* if the argument only affects the preprocessed output then
+ * it should not affect the compilation of the .c file
+ */
relpath = make_relative_path(x_strdup(argv[i+1]));
- args_add(stripped_args, relpath);
+ if (compopt_affects_cpp(argv[i])) {
+ args_add(cpp_args, argv[i]);
+ args_add(cpp_args, relpath);
+ } else {
+ args_add(stripped_args, argv[i]);
+ args_add(stripped_args, relpath);
+ }
/* Try to be smart about detecting precompiled headers */
if (str_eq(argv[i], "-include-pch")) {
char *option;
relpath = make_relative_path(x_strdup(argv[i] + 2));
option = format("-%c%s", argv[i][1], relpath);
- args_add(stripped_args, option);
+
+ /* if the argument only affects the preprocessed output then
+ * it should not affect the compilation of the .c file
+ */
+ if (compopt_short(compopt_affects_cpp, argv[i])) {
+ args_add(cpp_args, option);
+ } else {
+ args_add(stripped_args, option);
+ }
+
free(relpath);
free(option);
continue;
result = false;
goto out;
}
- args_add(stripped_args, argv[i]);
- args_add(stripped_args, argv[i+1]);
+
+ /* if the argument only affects the preprocessed output then
+ * it should not affect the compilation of the .c file
+ */
+ if (compopt_affects_cpp(argv[i])) {
+ args_add(cpp_args, argv[i]);
+ args_add(cpp_args, argv[i+1]);
+ } else {
+ args_add(stripped_args, argv[i]);
+ args_add(stripped_args, argv[i+1]);
+ }
+
i++;
continue;
}
/* other options */
if (argv[i][0] == '-') {
- args_add(stripped_args, argv[i]);
+ if (compopt_affects_cpp(argv[i]) ||
+ compopt_prefix_affects_cpp(argv[i])) {
+ args_add(cpp_args, argv[i]);
+ } else {
+ args_add(stripped_args, argv[i]);
+ }
continue;
}
* -finput-charset=XXX (otherwise conversion happens twice)
* -x XXX (otherwise the wrong language is selected)
*/
- *preprocessor_args = args_copy(stripped_args);
if (input_charset) {
- args_add(*preprocessor_args, input_charset);
+ args_add(cpp_args, input_charset);
}
if (found_pch) {
- args_add(*preprocessor_args, "-fpch-preprocess");
+ args_add(cpp_args, "-fpch-preprocess");
}
if (explicit_language) {
- args_add(*preprocessor_args, "-x");
- args_add(*preprocessor_args, explicit_language);
+ args_add(cpp_args, "-x");
+ args_add(cpp_args, explicit_language);
}
/*
}
}
+ *compiler_args = args_copy(stripped_args);
if (conf->run_second_cpp) {
- *compiler_args = args_copy(*preprocessor_args);
+ args_extend(*compiler_args, cpp_args);
} else {
- *compiler_args = args_copy(stripped_args);
if (explicit_language) {
/*
* Workaround for a bug in Apple's patched distcc -- it doesn't properly
* compiler doesn't produce a correct .d file when compiling preprocessed
* source.
*/
- args_extend(*preprocessor_args, dep_args);
+ args_extend(cpp_args, dep_args);
+
+ *preprocessor_args = args_copy(stripped_args);
+ args_extend(*preprocessor_args, cpp_args);
out:
args_free(expanded_args);
args_free(stripped_args);
args_free(dep_args);
+ args_free(cpp_args);
return result;
}
{"-Xassembler", TAKES_ARG},
{"-Xclang", TAKES_ARG},
{"-Xlinker", TAKES_ARG},
- {"-Xpreprocessor", TOO_HARD_DIRECT | TAKES_ARG},
+ {"-Xpreprocessor", AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG},
{"-arch", TAKES_ARG},
{"-aux-info", TAKES_ARG},
{"-b", TAKES_ARG},
+ {"-fno-working-directory", AFFECTS_CPP},
{"-frepo", TOO_HARD},
{"-ftest-coverage", TOO_HARD}, /* generates a .gcno file at the same time */
+ {"-fworking-directory", AFFECTS_CPP},
{"-idirafter", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
{"-iframework", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
{"-imacros", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
{"-iwithprefixbefore", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
{"-nostdinc", AFFECTS_CPP},
{"-nostdinc++", AFFECTS_CPP},
+ {"-remap", AFFECTS_CPP},
{"-save-temps", TOO_HARD},
+ {"-trigraphs", AFFECTS_CPP},
{"-u", TAKES_ARG},
};
+
static int
compare_compopts(const void *key1, const void *key2)
{
return strcmp(opt1->name, opt2->name);
}
+static int
+compare_prefix_compopts(const void *key1, const void *key2)
+{
+ const struct compopt *opt1 = (const struct compopt *)key1;
+ const struct compopt *opt2 = (const struct compopt *)key2;
+ return strncmp(opt1->name, opt2->name, strlen(opt2->name));
+}
+
static const struct compopt *
find(const char *option)
{
sizeof(compopts[0]), compare_compopts);
}
+static const struct compopt *
+find_prefix(const char *option)
+{
+ struct compopt key;
+ key.name = option;
+ return bsearch(
+ &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
+ sizeof(compopts[0]), compare_prefix_compopts);
+}
+
/* Runs fn on the first two characters of option. */
bool
compopt_short(bool (*fn)(const char *), const char *option)
const struct compopt *co = find(option);
return co && (co->type & TAKES_ARG);
}
+
+/* determines if argument takes a concatentated argument
+ by comparing prefixes
+*/
+bool
+compopt_takes_concat_arg(const char *option)
+{
+ const struct compopt *co = find_prefix(option);
+ return co && (co->type & TAKES_CONCAT_ARG);
+}
+
+/* determines if the prefix of the option matches
+ any option and affects the preprocessor
+*/
+bool
+compopt_prefix_affects_cpp(const char *option)
+{
+ /* prefix options have to take concatentated args */
+ const struct compopt *co = find_prefix(option);
+ return co && (co->type & TAKES_CONCAT_ARG) &&
+ (co->type & AFFECTS_CPP);
+}
bool compopt_too_hard_for_direct_mode(const char *option);
bool compopt_takes_path(const char *option);
bool compopt_takes_arg(const char *option);
+bool compopt_takes_concat_arg(const char *option);
+bool compopt_prefix_affects_cpp(const char *option);
#endif /* CCACHE_COMPOPT_H */
args_free(orig);
}
+TEST(preprocessor_only_flags_should_only_be_sent_to_the_preprocessor)
+{
+#define CMD \
+ "cc -I. -idirafter . -iframework. -imacros . -imultilib ." \
+ " -include test.h -include-pch test.pch -iprefix . -iquote ." \
+ " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ." \
+ " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory" \
+ " -fno-working-directory -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 "\
+ " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
+ struct args *orig = args_init_from_string(CMD " -c foo.c -o foo.o");
+ struct args *exp_cpp = args_init_from_string(CMD);
+#undef CMD
+ struct args *exp_cc = args_init_from_string("cc -c");
+ struct args *act_cpp = NULL, *act_cc = NULL;
+ create_file("foo.c", "");
+
+ CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+ CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+ CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+ args_free(orig);
+}
+
TEST(dependency_flags_that_take_an_argument_should_not_require_space_delimiter)
{
struct args *orig = args_init_from_string(
CHECK(!compopt_takes_arg("-xxx"));
}
+TEST(dash_iframework_prefix_affects_cpp)
+{
+ CHECK(compopt_prefix_affects_cpp("-iframework"));
+}
+
+
TEST_SUITE_END