From: Richard Smith Date: Wed, 4 Sep 2013 22:50:31 +0000 (+0000) Subject: Tweak implementation of -Wwrite-strings to better match the behavior of current GCCs: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e9813b386cb3012d11006cf7d3b2019688a5f502;p=clang Tweak implementation of -Wwrite-strings to better match the behavior of current GCCs: * In C, as before, if the "warning flag" is enabled, warnings are produced by forcing string literals to have const-qualified types (the produced warnings are *not* -Wwrite-strings warnings). However, more recent GCCs (at least 4.4 onwards) now take -w into account here, so we now do the same. * In C++, this flag is entirely sane: it behaves just like any other warning flag. Stop triggering -fconst-strings here. This is a bit cleaner, but there's no real functionality change except in the case where -Xclang -fno-const-strings is also specified. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190006 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 524247fe34..dd72fd748e 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2677,13 +2677,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_trigraphs); } - // Map the bizarre '-Wwrite-strings' flag to a more sensible - // '-fconst-strings'; this better indicates its actual behavior. - if (Args.hasFlag(options::OPT_Wwrite_strings, options::OPT_Wno_write_strings, - false)) { - // For perfect compatibility with GCC, we do this even in the presence of - // '-w'. This flag names something other than a warning for GCC. - CmdArgs.push_back("-fconst-strings"); + // GCC's behavior for -Wwrite-strings is a bit strange: + // * In C, this "warning flag" changes the types of string literals from + // 'char[N]' to 'const char[N]', and thus triggers an unrelated warning + // for the discarded qualifier. + // * In C++, this is just a normal warning flag. + // + // Implementing this warning correctly in C is hard, so we follow GCC's + // behavior for now. FIXME: Directly diagnose uses of a string literal as + // a non-const char* in C, rather than using this crude hack. + if (!types::isCXX(InputType)) { + // FIXME: This should behave just like a warning flag, and thus should also + // respect -Weverything, -Wno-everything, -Werror=write-strings, and so on. + Arg *WriteStrings = + Args.getLastArg(options::OPT_Wwrite_strings, + options::OPT_Wno_write_strings, options::OPT_w); + if (WriteStrings && + WriteStrings->getOption().matches(options::OPT_Wwrite_strings)) + CmdArgs.push_back("-fconst-strings"); } // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c index 0cf4cc910b..780b727de0 100644 --- a/test/Driver/clang_f_opts.c +++ b/test/Driver/clang_f_opts.c @@ -19,7 +19,7 @@ // RUN: %clang -### -S -Wwrite-strings -Wno-write-strings %s 2>&1 | FileCheck -check-prefix=WRITE-STRINGS2 %s // WRITE-STRINGS2-NOT: -fconst-strings // RUN: %clang -### -S -Wwrite-strings -w %s 2>&1 | FileCheck -check-prefix=WRITE-STRINGS3 %s -// WRITE-STRINGS3: -fconst-strings +// WRITE-STRINGS3-NOT: -fconst-strings // RUN: %clang -### -x c++ -c %s 2>&1 | FileCheck -check-prefix=DEPRECATED-ON-CHECK %s // RUN: %clang -### -x c++ -c -Wdeprecated %s 2>&1 | FileCheck -check-prefix=DEPRECATED-ON-CHECK %s