From: David Givone Date: Mon, 10 Sep 2012 00:08:15 +0000 (-0700) Subject: Don't pass preprocessor options to compiler during second compilation phase X-Git-Tag: v3.2~74 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1ea5033e2d0d8a53d16ba694cd8d5324e27dac2a;p=thirdparty%2Fccache.git Don't pass preprocessor options to compiler during second compilation phase 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. --- diff --git a/ccache.c b/ccache.c index 2973c7e2f..4b720ac7e 100644 --- a/ccache.c +++ b/ccache.c @@ -1431,7 +1431,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args, 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; @@ -1439,6 +1439,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args, 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; @@ -1779,6 +1780,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args, * 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; @@ -1789,9 +1791,17 @@ cc_process_args(struct args *args, struct args **preprocessor_args, 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")) { @@ -1840,7 +1850,16 @@ cc_process_args(struct args *args, struct args **preprocessor_args, 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; @@ -1854,15 +1873,30 @@ cc_process_args(struct args *args, struct args **preprocessor_args, 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; } @@ -2018,16 +2052,15 @@ cc_process_args(struct args *args, struct args **preprocessor_args, * -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); } /* @@ -2052,10 +2085,10 @@ cc_process_args(struct args *args, struct args **preprocessor_args, } } + *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 @@ -2076,12 +2109,16 @@ cc_process_args(struct args *args, struct args **preprocessor_args, * 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; } diff --git a/compopt.c b/compopt.c index ebdcc39e0..5c8682d10 100644 --- a/compopt.c +++ b/compopt.c @@ -51,12 +51,14 @@ static const struct compopt compopts[] = { {"-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}, @@ -72,10 +74,13 @@ static const struct compopt compopts[] = { {"-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) { @@ -84,6 +89,14 @@ 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) { @@ -94,6 +107,16 @@ 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) @@ -155,3 +178,25 @@ compopt_takes_arg(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); +} diff --git a/compopt.h b/compopt.h index 8985ac3d7..109094b66 100644 --- a/compopt.h +++ b/compopt.h @@ -9,5 +9,7 @@ bool compopt_too_hard(const char *option); 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 */ diff --git a/test/test_argument_processing.c b/test/test_argument_processing.c index 4ffe931ff..8ae128f36 100644 --- a/test/test_argument_processing.c +++ b/test/test_argument_processing.c @@ -72,6 +72,29 @@ TEST(dependency_flags_should_only_be_sent_to_the_preprocessor) 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( diff --git a/test/test_compopt.c b/test/test_compopt.c index 509825c8d..7a797d89c 100644 --- a/test/test_compopt.c +++ b/test/test_compopt.c @@ -94,4 +94,10 @@ TEST(dash_xxx_doesnt_take_arg) CHECK(!compopt_takes_arg("-xxx")); } +TEST(dash_iframework_prefix_affects_cpp) +{ + CHECK(compopt_prefix_affects_cpp("-iframework")); +} + + TEST_SUITE_END