]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r208987-format-extensions.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r208987-format-extensions.diff
1 This patch adds support for the FreeBSD-specific -fformat-extension option,
2 which enables additional printf modifiers for the kernel.
3
4 Introduced here: http://svnweb.freebsd.org/changeset/base/208987
5
6 Index: tools/clang/lib/Frontend/CompilerInvocation.cpp
7 ===================================================================
8 --- tools/clang/lib/Frontend/CompilerInvocation.cpp
9 +++ tools/clang/lib/Frontend/CompilerInvocation.cpp
10 @@ -1319,6 +1319,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgLi
11    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
12    Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
13    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
14 +  Opts.FormatExtensions = Args.hasArg(OPT_fformat_extensions);
15    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
16    Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
17    Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
18 Index: tools/clang/lib/Analysis/FormatString.cpp
19 ===================================================================
20 --- tools/clang/lib/Analysis/FormatString.cpp
21 +++ tools/clang/lib/Analysis/FormatString.cpp
22 @@ -548,6 +548,11 @@ const char *ConversionSpecifier::toString() const
23    // Objective-C specific specifiers.
24    case ObjCObjArg: return "@";
25  
26 +  // FreeBSD specific specifiers.
27 +  case FreeBSDbArg: return "b";
28 +  case FreeBSDDArg: return "D";
29 +  case FreeBSDrArg: return "r";
30 +
31    // GlibC specific specifiers.
32    case PrintErrno: return "m";
33    }
34 @@ -626,6 +631,7 @@ bool FormatSpecifier::hasValidLengthModifier(const
35          case ConversionSpecifier::xArg:
36          case ConversionSpecifier::XArg:
37          case ConversionSpecifier::nArg:
38 +        case ConversionSpecifier::FreeBSDrArg:
39            return true;
40          default:
41            return false;
42 @@ -654,6 +660,7 @@ bool FormatSpecifier::hasValidLengthModifier(const
43          case ConversionSpecifier::nArg:
44          case ConversionSpecifier::cArg:
45          case ConversionSpecifier::sArg:
46 +        case ConversionSpecifier::FreeBSDrArg:
47          case ConversionSpecifier::ScanListArg:
48            return true;
49          default:
50 @@ -774,6 +781,9 @@ bool FormatSpecifier::hasStandardConversionSpecifi
51      case ConversionSpecifier::SArg:
52        return LangOpt.ObjC1 || LangOpt.ObjC2;
53      case ConversionSpecifier::InvalidSpecifier:
54 +    case ConversionSpecifier::FreeBSDbArg:
55 +    case ConversionSpecifier::FreeBSDDArg:
56 +    case ConversionSpecifier::FreeBSDrArg:
57      case ConversionSpecifier::PrintErrno:
58      case ConversionSpecifier::DArg:
59      case ConversionSpecifier::OArg:
60 Index: tools/clang/lib/Analysis/PrintfFormatString.cpp
61 ===================================================================
62 --- tools/clang/lib/Analysis/PrintfFormatString.cpp
63 +++ tools/clang/lib/Analysis/PrintfFormatString.cpp
64 @@ -198,10 +198,25 @@ static PrintfSpecifierResult ParsePrintfSpecifier(
65      case '@': k = ConversionSpecifier::ObjCObjArg; break;
66      // Glibc specific.
67      case 'm': k = ConversionSpecifier::PrintErrno; break;
68 +    // FreeBSD format extensions
69 +    case 'b':
70 +      if (LO.FormatExtensions)
71 +        k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
72 +      break;
73 +    case 'r':
74 +      if (LO.FormatExtensions)
75 +        k = ConversionSpecifier::FreeBSDrArg;
76 +      break;
77 +    case 'y':
78 +      if (LO.FormatExtensions)
79 +        k = ConversionSpecifier::iArg;
80 +      break;
81      // Apple-specific
82      case 'D':
83        if (Target.getTriple().isOSDarwin())
84          k = ConversionSpecifier::DArg;
85 +      else if (LO.FormatExtensions)
86 +        k = ConversionSpecifier::FreeBSDDArg; // u_char * followed by char *
87        break;
88      case 'O':
89        if (Target.getTriple().isOSDarwin())
90 @@ -216,6 +231,10 @@ static PrintfSpecifierResult ParsePrintfSpecifier(
91    FS.setConversionSpecifier(CS);
92    if (CS.consumesDataArgument() && !FS.usesPositionalArg())
93      FS.setArgIndex(argIndex++);
94 +  // FreeBSD extension
95 +  if (k == ConversionSpecifier::FreeBSDbArg ||
96 +      k == ConversionSpecifier::FreeBSDDArg)
97 +    argIndex++;
98  
99    if (k == ConversionSpecifier::InvalidSpecifier) {
100      // Assume the conversion takes one argument.
101 @@ -618,6 +637,7 @@ bool PrintfSpecifier::hasValidPlusPrefix() const {
102    case ConversionSpecifier::GArg:
103    case ConversionSpecifier::aArg:
104    case ConversionSpecifier::AArg:
105 +  case ConversionSpecifier::FreeBSDrArg:
106      return true;
107  
108    default:
109 @@ -643,6 +663,7 @@ bool PrintfSpecifier::hasValidAlternativeForm() co
110    case ConversionSpecifier::FArg:
111    case ConversionSpecifier::gArg:
112    case ConversionSpecifier::GArg:
113 +  case ConversionSpecifier::FreeBSDrArg:
114      return true;
115  
116    default:
117 Index: tools/clang/lib/Sema/SemaChecking.cpp
118 ===================================================================
119 --- tools/clang/lib/Sema/SemaChecking.cpp
120 +++ tools/clang/lib/Sema/SemaChecking.cpp
121 @@ -2980,6 +2980,42 @@ CheckPrintfHandler::HandlePrintfSpecifier(const an
122      CoveredArgs.set(argIndex);
123    }
124  
125 +  // FreeBSD kernel extensions.
126 +  if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
127 +      CS.getKind() == ConversionSpecifier::FreeBSDDArg) { 
128 +    // We need at least two arguments.
129 +    if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
130 +      return false;
131 +
132 +    // Claim the second argument.
133 +    CoveredArgs.set(argIndex + 1);
134 +
135 +    // Type check the first argument (int for %b, pointer for %D)
136 +    const Expr *Ex = getDataArg(argIndex);
137 +    const analyze_printf::ArgType &AT =
138 +      (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
139 +        ArgType(S.Context.IntTy) : ArgType::CPointerTy;
140 +    if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType()))
141 +      S.Diag(getLocationOfByte(CS.getStart()),
142 +             diag::warn_printf_conversion_argument_type_mismatch)
143 +        << AT.getRepresentativeType(S.Context) << Ex->getType()
144 +        << getSpecifierRange(startSpecifier, specifierLen)
145 +        << Ex->getSourceRange();
146 +
147 +    // Type check the second argument (char * for both %b and %D)
148 +    Ex = getDataArg(argIndex + 1);
149 +    const analyze_printf::ArgType &AT2 = ArgType::CStrTy;
150 +    if (AT2.isValid() && !AT2.matchesType(S.Context, Ex->getType()))
151 +      S.Diag(getLocationOfByte(CS.getStart()),
152 +             diag::warn_printf_conversion_argument_type_mismatch)
153 +        << AT2.getRepresentativeType(S.Context) << Ex->getType()
154 +        << getSpecifierRange(startSpecifier, specifierLen)
155 +        << Ex->getSourceRange();
156 +
157 +     return true;
158 +  }
159 +  // END OF FREEBSD EXTENSIONS
160 +
161    // Check for using an Objective-C specific conversion specifier
162    // in a non-ObjC literal.
163    if (!ObjCContext && CS.isObjCArg()) {
164 Index: tools/clang/lib/Driver/Tools.cpp
165 ===================================================================
166 --- tools/clang/lib/Driver/Tools.cpp
167 +++ tools/clang/lib/Driver/Tools.cpp
168 @@ -2984,6 +2984,7 @@ void Clang::ConstructJob(Compilation &C, const Job
169  
170    // Forward -f (flag) options which we can pass directly.
171    Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
172 +  Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
173    Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
174    Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info);
175    Args.AddLastArg(CmdArgs, options::OPT_fno_limit_debug_info);
176 Index: tools/clang/include/clang/Basic/LangOptions.def
177 ===================================================================
178 --- tools/clang/include/clang/Basic/LangOptions.def
179 +++ tools/clang/include/clang/Basic/LangOptions.def
180 @@ -84,6 +84,7 @@ LANGOPT(TraditionalCPP    , 1, 0, "traditional CPP
181  LANGOPT(RTTI              , 1, 1, "run-time type information")
182  LANGOPT(MSBitfields       , 1, 0, "Microsoft-compatible structure layout")
183  LANGOPT(Freestanding, 1, 0, "freestanding implementation")
184 +LANGOPT(FormatExtensions  , 1, 0, "FreeBSD format extensions")
185  LANGOPT(NoBuiltin         , 1, 0, "disable builtin functions")
186  LANGOPT(NoMathBuiltin     , 1, 0, "disable math builtin functions")
187  
188 Index: tools/clang/include/clang/Analysis/Analyses/FormatString.h
189 ===================================================================
190 --- tools/clang/include/clang/Analysis/Analyses/FormatString.h
191 +++ tools/clang/include/clang/Analysis/Analyses/FormatString.h
192 @@ -158,6 +158,11 @@ class ConversionSpecifier {
193      ObjCObjArg,  // '@'
194      ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
195  
196 +    // FreeBSD specific specifiers
197 +    FreeBSDbArg,
198 +    FreeBSDDArg,
199 +    FreeBSDrArg,
200 +
201      // GlibC specific specifiers.
202      PrintErrno,   // 'm'
203  
204 Index: tools/clang/include/clang/Driver/Options.td
205 ===================================================================
206 --- tools/clang/include/clang/Driver/Options.td
207 +++ tools/clang/include/clang/Driver/Options.td
208 @@ -530,6 +530,8 @@ def fno_rewrite_includes : Flag<["-"], "fno-rewrit
209  
210  def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>,
211    HelpText<"Assert that the compilation takes place in a freestanding environment">;
212 +def fformat_extensions: Flag<["-"], "fformat-extensions">, Group<f_Group>, Flags<[CC1Option]>,
213 +  HelpText<"Enable FreeBSD kernel specific format string extensions">;
214  def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>,
215    HelpText<"Allow GNU-extension keywords regardless of language standard">;
216  def fgnu89_inline : Flag<["-"], "fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>,