Date: Thu, 10 Jun 2010 16:13:33 +0000 (UTC) From: Roman Divacky <rdivacky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r208987 - in head/contrib/llvm/tools/clang: include/clang/Analysis/Analyses include/clang/Basic include/clang/Driver lib/Analysis lib/Driver lib/Frontend lib/Sema Message-ID: <201006101613.o5AGDXHA099237@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rdivacky Date: Thu Jun 10 16:13:32 2010 New Revision: 208987 URL: http://svn.freebsd.org/changeset/base/208987 Log: Introduce -fformat-extensions. A local FreeBSD extension used for additional printf modifiers in kernel. Approved by: ed (mentor) Modified: head/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h head/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h head/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td head/contrib/llvm/tools/clang/include/clang/Driver/Options.td head/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp head/contrib/llvm/tools/clang/lib/Driver/Tools.cpp head/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp head/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp Modified: head/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/PrintfFormatString.h Thu Jun 10 16:13:32 2010 (r208987) @@ -57,6 +57,7 @@ public: InvalidSpecifier = 0, // C99 conversion specifiers. dArg, // 'd' + DArg, // 'D' FreeBSD specific specifiers iArg, // 'i', oArg, // 'o', uArg, // 'u', @@ -82,6 +83,7 @@ public: ObjCObjArg, // '@' // GlibC specific specifiers. PrintErrno, // 'm' + bArg, // FreeBSD specific specifiers // Specifier ranges. IntArgBeg = dArg, IntArgEnd = iArg, @@ -306,7 +308,7 @@ public: }; bool ParseFormatString(FormatStringHandler &H, - const char *beg, const char *end); + const char *beg, const char *end, bool FormatExtensions); } // end printf namespace } // end clang namespace Modified: head/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.h Thu Jun 10 16:13:32 2010 (r208987) @@ -54,6 +54,7 @@ public: unsigned NeXTRuntime : 1; // Use NeXT runtime. unsigned Freestanding : 1; // Freestanding implementation + unsigned FormatExtensions : 1; // FreeBSD format extensions (-fformat-extensions) unsigned NoBuiltin : 1; // Do not use builtin functions (-fno-builtin) unsigned ThreadsafeStatics : 1; // Whether static initializers are protected Modified: head/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td Thu Jun 10 16:13:32 2010 (r208987) @@ -377,6 +377,8 @@ def fsjlj_exceptions : Flag<"-fsjlj-exce HelpText<"Use SjLj style exceptions">; def ffreestanding : Flag<"-ffreestanding">, HelpText<"Assert that the compilation takes place in a freestanding environment">; +def fformat_extensions : Flag<"-fformat-extensions">, + HelpText<"FreeBSD printf format extensions">; def fgnu_runtime : Flag<"-fgnu-runtime">, HelpText<"Generate output compatible with the standard GNU Objective-C runtime">; def std_EQ : Joined<"-std=">, Modified: head/contrib/llvm/tools/clang/include/clang/Driver/Options.td ============================================================================== --- head/contrib/llvm/tools/clang/include/clang/Driver/Options.td Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/include/clang/Driver/Options.td Thu Jun 10 16:13:32 2010 (r208987) @@ -268,6 +268,7 @@ def fexceptions : Flag<"-fexceptions">, def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>; def fhosted : Flag<"-fhosted">, Group<f_Group>; def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>; +def fformat_extensions: Flag<"-fformat-extensions">; def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>; def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>; def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">; Modified: head/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/lib/Analysis/PrintfFormatString.cpp Thu Jun 10 16:13:32 2010 (r208987) @@ -210,7 +210,8 @@ static bool ParseArgPosition(FormatStrin static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, - unsigned &argIndex) { + unsigned &argIndex, + bool FormatExtensions) { using namespace clang::analyze_printf; @@ -369,11 +370,19 @@ static FormatSpecifierResult ParseFormat case '@': k = ConversionSpecifier::ObjCObjArg; break; // Glibc specific. case 'm': k = ConversionSpecifier::PrintErrno; break; + // FreeBSD format extensions + case 'b': if (FormatExtensions) k = ConversionSpecifier::bArg; break; /* check for int and then char * */ + case 'r': if (FormatExtensions) k = ConversionSpecifier::xArg; break; + case 'y': if (FormatExtensions) k = ConversionSpecifier::iArg; break; + case 'D': if (FormatExtensions) k = ConversionSpecifier::DArg; break; /* check for u_char * pointer and a char * string */ } ConversionSpecifier CS(conversionPosition, k); FS.setConversionSpecifier(CS); if (CS.consumesDataArgument() && !FS.usesPositionalArg()) FS.setArgIndex(argIndex++); + // FreeBSD extension + if (k == ConversionSpecifier::bArg || k == ConversionSpecifier::DArg) + argIndex++; if (k == ConversionSpecifier::InvalidSpecifier) { // Assume the conversion takes one argument. @@ -383,13 +392,13 @@ static FormatSpecifierResult ParseFormat } bool clang::analyze_printf::ParseFormatString(FormatStringHandler &H, - const char *I, const char *E) { + const char *I, const char *E, bool FormatExtensions) { unsigned argIndex = 0; // Keep looking for a format specifier until we have exhausted the string. while (I != E) { - const FormatSpecifierResult &FSR = ParseFormatSpecifier(H, I, E, argIndex); + const FormatSpecifierResult &FSR = ParseFormatSpecifier(H, I, E, argIndex, FormatExtensions); // Did a fail-stop error of any kind occur when parsing the specifier? // If so, don't do any more processing. if (FSR.shouldStop()) Modified: head/contrib/llvm/tools/clang/lib/Driver/Tools.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Driver/Tools.cpp Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/lib/Driver/Tools.cpp Thu Jun 10 16:13:32 2010 (r208987) @@ -1156,6 +1156,7 @@ void Clang::ConstructJob(Compilation &C, Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior); Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); + Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions); // -flax-vector-conversions is default. if (!Args.hasFlag(options::OPT_flax_vector_conversions, Modified: head/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp Thu Jun 10 16:13:32 2010 (r208987) @@ -530,6 +530,8 @@ static void LangOptsToArgs(const LangOpt Res.push_back("-fgnu-runtime"); if (Opts.Freestanding) Res.push_back("-ffreestanding"); + if (Opts.FormatExtensions) + Res.push_back("-fformat-extensions"); if (Opts.NoBuiltin) Res.push_back("-fno-builtin"); if (!Opts.AssumeSaneOperatorNew) @@ -1245,6 +1247,7 @@ static void ParseLangArgs(LangOptions &O Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char); Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar); Opts.Freestanding = Args.hasArg(OPT_ffreestanding); + Opts.FormatExtensions = Args.hasArg(OPT_fformat_extensions); Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); Modified: head/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp ============================================================================== --- head/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp Thu Jun 10 14:19:51 2010 (r208986) +++ head/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp Thu Jun 10 16:13:32 2010 (r208987) @@ -1276,6 +1276,39 @@ CheckPrintfHandler::HandleFormatSpecifie CoveredArgs.set(argIndex); } + // FreeBSD extensions + if (CS.getKind() == ConversionSpecifier::bArg || CS.getKind() == ConversionSpecifier::DArg) { + // claim the second argument + CoveredArgs.set(argIndex + 1); + + // Now type check the data expression that matches the + // format specifier. + const Expr *Ex = getDataArg(argIndex); + QualType type = (CS.getKind() == ConversionSpecifier::bArg) ? S.Context.IntTy : S.Context.getPointerType(S.Context.UnsignedCharTy); + //const analyze_printf::ArgTypeResult &ATR = S.Context.IntTy; + const analyze_printf::ArgTypeResult &ATR = type; + if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) + S.Diag(getLocationOfByte(CS.getStart()), + diag::warn_printf_conversion_argument_type_mismatch) + << ATR.getRepresentativeType(S.Context) << Ex->getType() + << getFormatSpecifierRange(startSpecifier, specifierLen) + << Ex->getSourceRange(); + + // Now type check the data expression that matches the + // format specifier. + Ex = getDataArg(argIndex + 1); + const analyze_printf::ArgTypeResult &ATR2 = ArgTypeResult::CStrTy; + if (ATR2.isValid() && !ATR2.matchesType(S.Context, Ex->getType())) + S.Diag(getLocationOfByte(CS.getStart()), + diag::warn_printf_conversion_argument_type_mismatch) + << ATR2.getRepresentativeType(S.Context) << Ex->getType() + << getFormatSpecifierRange(startSpecifier, specifierLen) + << Ex->getSourceRange(); + + return true; + } + // END OF FREEBSD EXTENSIONS + // Check for using an Objective-C specific conversion specifier // in a non-ObjC literal. if (!IsObjCLiteral && CS.isObjCArg()) { @@ -1400,7 +1433,8 @@ void Sema::CheckPrintfString(const Strin isa<ObjCStringLiteral>(OrigFormatExpr), Str, HasVAListArg, TheCall, format_idx); - if (!analyze_printf::ParseFormatString(H, Str, Str + StrLen)) + bool FormatExtensions = getLangOptions().FormatExtensions; + if (!analyze_printf::ParseFormatString(H, Str, Str + StrLen, FormatExtensions)) H.DoneProcessing(); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006101613.o5AGDXHA099237>