/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Sema/SemaChecking.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- SemaChecking.cpp - Extra Semantic Checking -------------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file implements extra semantic analysis beyond what is enforced |
10 | | // by the C type system. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "clang/AST/APValue.h" |
15 | | #include "clang/AST/ASTContext.h" |
16 | | #include "clang/AST/Attr.h" |
17 | | #include "clang/AST/AttrIterator.h" |
18 | | #include "clang/AST/CharUnits.h" |
19 | | #include "clang/AST/Decl.h" |
20 | | #include "clang/AST/DeclBase.h" |
21 | | #include "clang/AST/DeclCXX.h" |
22 | | #include "clang/AST/DeclObjC.h" |
23 | | #include "clang/AST/DeclarationName.h" |
24 | | #include "clang/AST/EvaluatedExprVisitor.h" |
25 | | #include "clang/AST/Expr.h" |
26 | | #include "clang/AST/ExprCXX.h" |
27 | | #include "clang/AST/ExprObjC.h" |
28 | | #include "clang/AST/ExprOpenMP.h" |
29 | | #include "clang/AST/FormatString.h" |
30 | | #include "clang/AST/NSAPI.h" |
31 | | #include "clang/AST/NonTrivialTypeVisitor.h" |
32 | | #include "clang/AST/OperationKinds.h" |
33 | | #include "clang/AST/RecordLayout.h" |
34 | | #include "clang/AST/Stmt.h" |
35 | | #include "clang/AST/TemplateBase.h" |
36 | | #include "clang/AST/Type.h" |
37 | | #include "clang/AST/TypeLoc.h" |
38 | | #include "clang/AST/UnresolvedSet.h" |
39 | | #include "clang/Basic/AddressSpaces.h" |
40 | | #include "clang/Basic/CharInfo.h" |
41 | | #include "clang/Basic/Diagnostic.h" |
42 | | #include "clang/Basic/IdentifierTable.h" |
43 | | #include "clang/Basic/LLVM.h" |
44 | | #include "clang/Basic/LangOptions.h" |
45 | | #include "clang/Basic/OpenCLOptions.h" |
46 | | #include "clang/Basic/OperatorKinds.h" |
47 | | #include "clang/Basic/PartialDiagnostic.h" |
48 | | #include "clang/Basic/SourceLocation.h" |
49 | | #include "clang/Basic/SourceManager.h" |
50 | | #include "clang/Basic/Specifiers.h" |
51 | | #include "clang/Basic/SyncScope.h" |
52 | | #include "clang/Basic/TargetBuiltins.h" |
53 | | #include "clang/Basic/TargetCXXABI.h" |
54 | | #include "clang/Basic/TargetInfo.h" |
55 | | #include "clang/Basic/TypeTraits.h" |
56 | | #include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering. |
57 | | #include "clang/Sema/Initialization.h" |
58 | | #include "clang/Sema/Lookup.h" |
59 | | #include "clang/Sema/Ownership.h" |
60 | | #include "clang/Sema/Scope.h" |
61 | | #include "clang/Sema/ScopeInfo.h" |
62 | | #include "clang/Sema/Sema.h" |
63 | | #include "clang/Sema/SemaInternal.h" |
64 | | #include "llvm/ADT/APFloat.h" |
65 | | #include "llvm/ADT/APInt.h" |
66 | | #include "llvm/ADT/APSInt.h" |
67 | | #include "llvm/ADT/ArrayRef.h" |
68 | | #include "llvm/ADT/DenseMap.h" |
69 | | #include "llvm/ADT/FoldingSet.h" |
70 | | #include "llvm/ADT/None.h" |
71 | | #include "llvm/ADT/Optional.h" |
72 | | #include "llvm/ADT/STLExtras.h" |
73 | | #include "llvm/ADT/SmallBitVector.h" |
74 | | #include "llvm/ADT/SmallPtrSet.h" |
75 | | #include "llvm/ADT/SmallString.h" |
76 | | #include "llvm/ADT/SmallVector.h" |
77 | | #include "llvm/ADT/StringRef.h" |
78 | | #include "llvm/ADT/StringSet.h" |
79 | | #include "llvm/ADT/StringSwitch.h" |
80 | | #include "llvm/ADT/Triple.h" |
81 | | #include "llvm/Support/AtomicOrdering.h" |
82 | | #include "llvm/Support/Casting.h" |
83 | | #include "llvm/Support/Compiler.h" |
84 | | #include "llvm/Support/ConvertUTF.h" |
85 | | #include "llvm/Support/ErrorHandling.h" |
86 | | #include "llvm/Support/Format.h" |
87 | | #include "llvm/Support/Locale.h" |
88 | | #include "llvm/Support/MathExtras.h" |
89 | | #include "llvm/Support/SaveAndRestore.h" |
90 | | #include "llvm/Support/raw_ostream.h" |
91 | | #include <algorithm> |
92 | | #include <bitset> |
93 | | #include <cassert> |
94 | | #include <cctype> |
95 | | #include <cstddef> |
96 | | #include <cstdint> |
97 | | #include <functional> |
98 | | #include <limits> |
99 | | #include <string> |
100 | | #include <tuple> |
101 | | #include <utility> |
102 | | |
103 | | using namespace clang; |
104 | | using namespace sema; |
105 | | |
106 | | SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL, |
107 | 24 | unsigned ByteNo) const { |
108 | 24 | return SL->getLocationOfByte(ByteNo, getSourceManager(), LangOpts, |
109 | 24 | Context.getTargetInfo()); |
110 | 24 | } |
111 | | |
112 | | static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, |
113 | 55 | Sema::FormatArgumentPassingKind B) { |
114 | 55 | return (A << 8) | B; |
115 | 55 | } |
116 | | |
117 | | /// Checks that a call expression's argument count is at least the desired |
118 | | /// number. This is useful when doing custom type-checking on a variadic |
119 | | /// function. Returns true on error. |
120 | | static bool checkArgCountAtLeast(Sema &S, CallExpr *Call, |
121 | 154 | unsigned MinArgCount) { |
122 | 154 | unsigned ArgCount = Call->getNumArgs(); |
123 | 154 | if (ArgCount >= MinArgCount) |
124 | 83 | return false; |
125 | | |
126 | 71 | return S.Diag(Call->getEndLoc(), diag::err_typecheck_call_too_few_args) |
127 | 71 | << 0 /*function call*/ << MinArgCount << ArgCount |
128 | 71 | << Call->getSourceRange(); |
129 | 154 | } |
130 | | |
131 | | /// Checks that a call expression's argument count is the desired number. |
132 | | /// This is useful when doing custom type-checking. Returns true on error. |
133 | 94.6k | static bool checkArgCount(Sema &S, CallExpr *Call, unsigned DesiredArgCount) { |
134 | 94.6k | unsigned ArgCount = Call->getNumArgs(); |
135 | 94.6k | if (ArgCount == DesiredArgCount) |
136 | 94.4k | return false; |
137 | | |
138 | 128 | if (checkArgCountAtLeast(S, Call, DesiredArgCount)) |
139 | 67 | return true; |
140 | 61 | assert(ArgCount > DesiredArgCount && "should have diagnosed this"); |
141 | | |
142 | | // Highlight all the excess arguments. |
143 | 0 | SourceRange Range(Call->getArg(DesiredArgCount)->getBeginLoc(), |
144 | 61 | Call->getArg(ArgCount - 1)->getEndLoc()); |
145 | | |
146 | 61 | return S.Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args) |
147 | 61 | << 0 /*function call*/ << DesiredArgCount << ArgCount |
148 | 61 | << Call->getArg(1)->getSourceRange(); |
149 | 128 | } |
150 | | |
151 | | /// Check that the first argument to __builtin_annotation is an integer |
152 | | /// and the second argument is a non-wide string literal. |
153 | 12 | static bool SemaBuiltinAnnotation(Sema &S, CallExpr *TheCall) { |
154 | 12 | if (checkArgCount(S, TheCall, 2)) |
155 | 0 | return true; |
156 | | |
157 | | // First argument should be an integer. |
158 | 12 | Expr *ValArg = TheCall->getArg(0); |
159 | 12 | QualType Ty = ValArg->getType(); |
160 | 12 | if (!Ty->isIntegerType()) { |
161 | 1 | S.Diag(ValArg->getBeginLoc(), diag::err_builtin_annotation_first_arg) |
162 | 1 | << ValArg->getSourceRange(); |
163 | 1 | return true; |
164 | 1 | } |
165 | | |
166 | | // Second argument should be a constant string. |
167 | 11 | Expr *StrArg = TheCall->getArg(1)->IgnoreParenCasts(); |
168 | 11 | StringLiteral *Literal = dyn_cast<StringLiteral>(StrArg); |
169 | 11 | if (!Literal || !Literal->isOrdinary()10 ) { |
170 | 2 | S.Diag(StrArg->getBeginLoc(), diag::err_builtin_annotation_second_arg) |
171 | 2 | << StrArg->getSourceRange(); |
172 | 2 | return true; |
173 | 2 | } |
174 | | |
175 | 9 | TheCall->setType(Ty); |
176 | 9 | return false; |
177 | 11 | } |
178 | | |
179 | 31 | static bool SemaBuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall) { |
180 | | // We need at least one argument. |
181 | 31 | if (TheCall->getNumArgs() < 1) { |
182 | 3 | S.Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) |
183 | 3 | << 0 << 1 << TheCall->getNumArgs() |
184 | 3 | << TheCall->getCallee()->getSourceRange(); |
185 | 3 | return true; |
186 | 3 | } |
187 | | |
188 | | // All arguments should be wide string literals. |
189 | 49 | for (Expr *Arg : TheCall->arguments())28 { |
190 | 49 | auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts()); |
191 | 49 | if (!Literal || !Literal->isWide()43 ) { |
192 | 6 | S.Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str) |
193 | 6 | << Arg->getSourceRange(); |
194 | 6 | return true; |
195 | 6 | } |
196 | 49 | } |
197 | | |
198 | 22 | return false; |
199 | 28 | } |
200 | | |
201 | | /// Check that the argument to __builtin_addressof is a glvalue, and set the |
202 | | /// result type to the corresponding pointer type. |
203 | 188 | static bool SemaBuiltinAddressof(Sema &S, CallExpr *TheCall) { |
204 | 188 | if (checkArgCount(S, TheCall, 1)) |
205 | 0 | return true; |
206 | | |
207 | 188 | ExprResult Arg(TheCall->getArg(0)); |
208 | 188 | QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getBeginLoc()); |
209 | 188 | if (ResultType.isNull()) |
210 | 2 | return true; |
211 | | |
212 | 186 | TheCall->setArg(0, Arg.get()); |
213 | 186 | TheCall->setType(ResultType); |
214 | 186 | return false; |
215 | 188 | } |
216 | | |
217 | | /// Check that the argument to __builtin_function_start is a function. |
218 | 14 | static bool SemaBuiltinFunctionStart(Sema &S, CallExpr *TheCall) { |
219 | 14 | if (checkArgCount(S, TheCall, 1)) |
220 | 0 | return true; |
221 | | |
222 | 14 | ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); |
223 | 14 | if (Arg.isInvalid()) |
224 | 0 | return true; |
225 | | |
226 | 14 | TheCall->setArg(0, Arg.get()); |
227 | 14 | const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>( |
228 | 14 | Arg.get()->getAsBuiltinConstantDeclRef(S.getASTContext())); |
229 | | |
230 | 14 | if (!FD) { |
231 | 2 | S.Diag(TheCall->getBeginLoc(), diag::err_function_start_invalid_type) |
232 | 2 | << TheCall->getSourceRange(); |
233 | 2 | return true; |
234 | 2 | } |
235 | | |
236 | 12 | return !S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, |
237 | 12 | TheCall->getBeginLoc()); |
238 | 14 | } |
239 | | |
240 | | /// Check the number of arguments and set the result type to |
241 | | /// the argument type. |
242 | 29 | static bool SemaBuiltinPreserveAI(Sema &S, CallExpr *TheCall) { |
243 | 29 | if (checkArgCount(S, TheCall, 1)) |
244 | 1 | return true; |
245 | | |
246 | 28 | TheCall->setType(TheCall->getArg(0)->getType()); |
247 | 28 | return false; |
248 | 29 | } |
249 | | |
250 | | /// Check that the value argument for __builtin_is_aligned(value, alignment) and |
251 | | /// __builtin_aligned_{up,down}(value, alignment) is an integer or a pointer |
252 | | /// type (but not a function pointer) and that the alignment is a power-of-two. |
253 | 281 | static bool SemaBuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID) { |
254 | 281 | if (checkArgCount(S, TheCall, 2)) |
255 | 1 | return true; |
256 | | |
257 | 280 | clang::Expr *Source = TheCall->getArg(0); |
258 | 280 | bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned; |
259 | | |
260 | 406 | auto IsValidIntegerType = [](QualType Ty) { |
261 | 406 | return Ty->isIntegerType() && !Ty->isEnumeralType()386 && !Ty->isBooleanType()380 ; |
262 | 406 | }; |
263 | 280 | QualType SrcTy = Source->getType(); |
264 | | // We should also be able to use it with arrays (but not functions!). |
265 | 280 | if (SrcTy->canDecayToPointerType() && SrcTy->isArrayType()24 ) { |
266 | 21 | SrcTy = S.Context.getDecayedType(SrcTy); |
267 | 21 | } |
268 | 280 | if ((!SrcTy->isPointerType() && !IsValidIntegerType(SrcTy)150 ) || |
269 | 280 | SrcTy->isFunctionPointerType()259 ) { |
270 | | // FIXME: this is not quite the right error message since we don't allow |
271 | | // floating point types, or member pointers. |
272 | 24 | S.Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand) |
273 | 24 | << SrcTy; |
274 | 24 | return true; |
275 | 24 | } |
276 | | |
277 | 256 | clang::Expr *AlignOp = TheCall->getArg(1); |
278 | 256 | if (!IsValidIntegerType(AlignOp->getType())) { |
279 | 12 | S.Diag(AlignOp->getExprLoc(), diag::err_typecheck_expect_int) |
280 | 12 | << AlignOp->getType(); |
281 | 12 | return true; |
282 | 12 | } |
283 | 244 | Expr::EvalResult AlignResult; |
284 | 244 | unsigned MaxAlignmentBits = S.Context.getIntWidth(SrcTy) - 1; |
285 | | // We can't check validity of alignment if it is value dependent. |
286 | 244 | if (!AlignOp->isValueDependent() && |
287 | 244 | AlignOp->EvaluateAsInt(AlignResult, S.Context, |
288 | 243 | Expr::SE_AllowSideEffects)) { |
289 | 196 | llvm::APSInt AlignValue = AlignResult.Val.getInt(); |
290 | 196 | llvm::APSInt MaxValue( |
291 | 196 | llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits)); |
292 | 196 | if (AlignValue < 1) { |
293 | 4 | S.Diag(AlignOp->getExprLoc(), diag::err_alignment_too_small) << 1; |
294 | 4 | return true; |
295 | 4 | } |
296 | 192 | if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) { |
297 | 15 | S.Diag(AlignOp->getExprLoc(), diag::err_alignment_too_big) |
298 | 15 | << toString(MaxValue, 10); |
299 | 15 | return true; |
300 | 15 | } |
301 | 177 | if (!AlignValue.isPowerOf2()) { |
302 | 16 | S.Diag(AlignOp->getExprLoc(), diag::err_alignment_not_power_of_two); |
303 | 16 | return true; |
304 | 16 | } |
305 | 161 | if (AlignValue == 1) { |
306 | 3 | S.Diag(AlignOp->getExprLoc(), diag::warn_alignment_builtin_useless) |
307 | 3 | << IsBooleanAlignBuiltin; |
308 | 3 | } |
309 | 161 | } |
310 | | |
311 | 209 | ExprResult SrcArg = S.PerformCopyInitialization( |
312 | 209 | InitializedEntity::InitializeParameter(S.Context, SrcTy, false), |
313 | 209 | SourceLocation(), Source); |
314 | 209 | if (SrcArg.isInvalid()) |
315 | 0 | return true; |
316 | 209 | TheCall->setArg(0, SrcArg.get()); |
317 | 209 | ExprResult AlignArg = |
318 | 209 | S.PerformCopyInitialization(InitializedEntity::InitializeParameter( |
319 | 209 | S.Context, AlignOp->getType(), false), |
320 | 209 | SourceLocation(), AlignOp); |
321 | 209 | if (AlignArg.isInvalid()) |
322 | 0 | return true; |
323 | 209 | TheCall->setArg(1, AlignArg.get()); |
324 | | // For align_up/align_down, the return type is the same as the (potentially |
325 | | // decayed) argument type including qualifiers. For is_aligned(), the result |
326 | | // is always bool. |
327 | 209 | TheCall->setType(IsBooleanAlignBuiltin ? S.Context.BoolTy71 : SrcTy138 ); |
328 | 209 | return false; |
329 | 209 | } |
330 | | |
331 | | static bool SemaBuiltinOverflow(Sema &S, CallExpr *TheCall, |
332 | 112 | unsigned BuiltinID) { |
333 | 112 | if (checkArgCount(S, TheCall, 3)) |
334 | 2 | return true; |
335 | | |
336 | | // First two arguments should be integers. |
337 | 327 | for (unsigned I = 0; 110 I < 2; ++I217 ) { |
338 | 219 | ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(I)); |
339 | 219 | if (Arg.isInvalid()) return true0 ; |
340 | 219 | TheCall->setArg(I, Arg.get()); |
341 | | |
342 | 219 | QualType Ty = Arg.get()->getType(); |
343 | 219 | if (!Ty->isIntegerType()) { |
344 | 2 | S.Diag(Arg.get()->getBeginLoc(), diag::err_overflow_builtin_must_be_int) |
345 | 2 | << Ty << Arg.get()->getSourceRange(); |
346 | 2 | return true; |
347 | 2 | } |
348 | 219 | } |
349 | | |
350 | | // Third argument should be a pointer to a non-const integer. |
351 | | // IRGen correctly handles volatile, restrict, and address spaces, and |
352 | | // the other qualifiers aren't possible. |
353 | 108 | { |
354 | 108 | ExprResult Arg = S.DefaultFunctionArrayLvalueConversion(TheCall->getArg(2)); |
355 | 108 | if (Arg.isInvalid()) return true0 ; |
356 | 108 | TheCall->setArg(2, Arg.get()); |
357 | | |
358 | 108 | QualType Ty = Arg.get()->getType(); |
359 | 108 | const auto *PtrTy = Ty->getAs<PointerType>(); |
360 | 108 | if (!PtrTy || |
361 | 108 | !PtrTy->getPointeeType()->isIntegerType()107 || |
362 | 108 | PtrTy->getPointeeType().isConstQualified()106 ) { |
363 | 3 | S.Diag(Arg.get()->getBeginLoc(), |
364 | 3 | diag::err_overflow_builtin_must_be_ptr_int) |
365 | 3 | << Ty << Arg.get()->getSourceRange(); |
366 | 3 | return true; |
367 | 3 | } |
368 | 108 | } |
369 | | |
370 | | // Disallow signed bit-precise integer args larger than 128 bits to mul |
371 | | // function until we improve backend support. |
372 | 105 | if (BuiltinID == Builtin::BI__builtin_mul_overflow) { |
373 | 236 | for (unsigned I = 0; I < 3; ++I177 ) { |
374 | 177 | const auto Arg = TheCall->getArg(I); |
375 | | // Third argument will be a pointer. |
376 | 177 | auto Ty = I < 2 ? Arg->getType()118 : Arg->getType()->getPointeeType()59 ; |
377 | 177 | if (Ty->isBitIntType() && Ty->isSignedIntegerType()30 && |
378 | 177 | S.getASTContext().getIntWidth(Ty) > 12830 ) |
379 | 0 | return S.Diag(Arg->getBeginLoc(), |
380 | 0 | diag::err_overflow_builtin_bit_int_max_size) |
381 | 0 | << 128; |
382 | 177 | } |
383 | 59 | } |
384 | | |
385 | 105 | return false; |
386 | 105 | } |
387 | | |
388 | | namespace { |
389 | | struct BuiltinDumpStructGenerator { |
390 | | Sema &S; |
391 | | CallExpr *TheCall; |
392 | | SourceLocation Loc = TheCall->getBeginLoc(); |
393 | | SmallVector<Expr *, 32> Actions; |
394 | | DiagnosticErrorTrap ErrorTracker; |
395 | | PrintingPolicy Policy; |
396 | | |
397 | | BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall) |
398 | | : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()), |
399 | 16 | Policy(S.Context.getPrintingPolicy()) { |
400 | 16 | Policy.AnonymousTagLocations = false; |
401 | 16 | } |
402 | | |
403 | 20 | Expr *makeOpaqueValueExpr(Expr *Inner) { |
404 | 20 | auto *OVE = new (S.Context) |
405 | 20 | OpaqueValueExpr(Loc, Inner->getType(), Inner->getValueKind(), |
406 | 20 | Inner->getObjectKind(), Inner); |
407 | 20 | Actions.push_back(OVE); |
408 | 20 | return OVE; |
409 | 20 | } |
410 | | |
411 | 248 | Expr *getStringLiteral(llvm::StringRef Str) { |
412 | 248 | Expr *Lit = S.Context.getPredefinedStringLiteralFromCache(Str); |
413 | | // Wrap the literal in parentheses to attach a source location. |
414 | 248 | return new (S.Context) ParenExpr(Loc, Loc, Lit); |
415 | 248 | } |
416 | | |
417 | | bool callPrintFunction(llvm::StringRef Format, |
418 | 108 | llvm::ArrayRef<Expr *> Exprs = {}) { |
419 | 108 | SmallVector<Expr *, 8> Args; |
420 | 108 | assert(TheCall->getNumArgs() >= 2); |
421 | 0 | Args.reserve((TheCall->getNumArgs() - 2) + /*Format*/ 1 + Exprs.size()); |
422 | 108 | Args.assign(TheCall->arg_begin() + 2, TheCall->arg_end()); |
423 | 108 | Args.push_back(getStringLiteral(Format)); |
424 | 108 | Args.insert(Args.end(), Exprs.begin(), Exprs.end()); |
425 | | |
426 | | // Register a note to explain why we're performing the call. |
427 | 108 | Sema::CodeSynthesisContext Ctx; |
428 | 108 | Ctx.Kind = Sema::CodeSynthesisContext::BuildingBuiltinDumpStructCall; |
429 | 108 | Ctx.PointOfInstantiation = Loc; |
430 | 108 | Ctx.CallArgs = Args.data(); |
431 | 108 | Ctx.NumCallArgs = Args.size(); |
432 | 108 | S.pushCodeSynthesisContext(Ctx); |
433 | | |
434 | 108 | ExprResult RealCall = |
435 | 108 | S.BuildCallExpr(/*Scope=*/nullptr, TheCall->getArg(1), |
436 | 108 | TheCall->getBeginLoc(), Args, TheCall->getRParenLoc()); |
437 | | |
438 | 108 | S.popCodeSynthesisContext(); |
439 | 108 | if (!RealCall.isInvalid()) |
440 | 106 | Actions.push_back(RealCall.get()); |
441 | | // Bail out if we've hit any errors, even if we managed to build the |
442 | | // call. We don't want to produce more than one error. |
443 | 108 | return RealCall.isInvalid() || ErrorTracker.hasErrorOccurred()106 ; |
444 | 108 | } |
445 | | |
446 | 39 | Expr *getIndentString(unsigned Depth) { |
447 | 39 | if (!Depth) |
448 | 16 | return nullptr; |
449 | | |
450 | 23 | llvm::SmallString<32> Indent; |
451 | 23 | Indent.resize(Depth * Policy.Indentation, ' '); |
452 | 23 | return getStringLiteral(Indent); |
453 | 39 | } |
454 | | |
455 | 68 | Expr *getTypeString(QualType T) { |
456 | 68 | return getStringLiteral(T.getAsString(Policy)); |
457 | 68 | } |
458 | | |
459 | 45 | bool appendFormatSpecifier(QualType T, llvm::SmallVectorImpl<char> &Str) { |
460 | 45 | llvm::raw_svector_ostream OS(Str); |
461 | | |
462 | | // Format 'bool', 'char', 'signed char', 'unsigned char' as numbers, rather |
463 | | // than trying to print a single character. |
464 | 45 | if (auto *BT = T->getAs<BuiltinType>()) { |
465 | 36 | switch (BT->getKind()) { |
466 | 0 | case BuiltinType::Bool: |
467 | 0 | OS << "%d"; |
468 | 0 | return true; |
469 | 0 | case BuiltinType::Char_U: |
470 | 1 | case BuiltinType::UChar: |
471 | 1 | OS << "%hhu"; |
472 | 1 | return true; |
473 | 1 | case BuiltinType::Char_S: |
474 | 2 | case BuiltinType::SChar: |
475 | 2 | OS << "%hhd"; |
476 | 2 | return true; |
477 | 33 | default: |
478 | 33 | break; |
479 | 36 | } |
480 | 36 | } |
481 | | |
482 | 42 | analyze_printf::PrintfSpecifier Specifier; |
483 | 42 | if (Specifier.fixType(T, S.getLangOpts(), S.Context, /*IsObjCLiteral=*/false)) { |
484 | | // We were able to guess how to format this. |
485 | 35 | if (Specifier.getConversionSpecifier().getKind() == |
486 | 35 | analyze_printf::PrintfConversionSpecifier::sArg) { |
487 | | // Wrap double-quotes around a '%s' specifier and limit its maximum |
488 | | // length. Ideally we'd also somehow escape special characters in the |
489 | | // contents but printf doesn't support that. |
490 | | // FIXME: '%s' formatting is not safe in general. |
491 | 2 | OS << '"'; |
492 | 2 | Specifier.setPrecision(analyze_printf::OptionalAmount(32u)); |
493 | 2 | Specifier.toString(OS); |
494 | 2 | OS << '"'; |
495 | | // FIXME: It would be nice to include a '...' if the string doesn't fit |
496 | | // in the length limit. |
497 | 33 | } else { |
498 | 33 | Specifier.toString(OS); |
499 | 33 | } |
500 | 35 | return true; |
501 | 35 | } |
502 | | |
503 | 7 | if (T->isPointerType()) { |
504 | | // Format all pointers with '%p'. |
505 | 1 | OS << "%p"; |
506 | 1 | return true; |
507 | 1 | } |
508 | | |
509 | 6 | return false; |
510 | 7 | } |
511 | | |
512 | 19 | bool dumpUnnamedRecord(const RecordDecl *RD, Expr *E, unsigned Depth) { |
513 | 19 | Expr *IndentLit = getIndentString(Depth); |
514 | 19 | Expr *TypeLit = getTypeString(S.Context.getRecordType(RD)); |
515 | 19 | if (IndentLit ? callPrintFunction("%s%s", {IndentLit, TypeLit})3 |
516 | 19 | : callPrintFunction("%s", {TypeLit})16 ) |
517 | 3 | return true; |
518 | | |
519 | 16 | return dumpRecordValue(RD, E, IndentLit, Depth); |
520 | 19 | } |
521 | | |
522 | | // Dump a record value. E should be a pointer or lvalue referring to an RD. |
523 | | bool dumpRecordValue(const RecordDecl *RD, Expr *E, Expr *RecordIndent, |
524 | 20 | unsigned Depth) { |
525 | | // FIXME: Decide what to do if RD is a union. At least we should probably |
526 | | // turn off printing `const char*` members with `%s`, because that is very |
527 | | // likely to crash if that's not the active member. Whatever we decide, we |
528 | | // should document it. |
529 | | |
530 | | // Build an OpaqueValueExpr so we can refer to E more than once without |
531 | | // triggering re-evaluation. |
532 | 20 | Expr *RecordArg = makeOpaqueValueExpr(E); |
533 | 20 | bool RecordArgIsPtr = RecordArg->getType()->isPointerType(); |
534 | | |
535 | 20 | if (callPrintFunction(" {\n")) |
536 | 0 | return true; |
537 | | |
538 | | // Dump each base class, regardless of whether they're aggregates. |
539 | 20 | if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { |
540 | 8 | for (const auto &Base : CXXRD->bases()) { |
541 | 3 | QualType BaseType = |
542 | 3 | RecordArgIsPtr ? S.Context.getPointerType(Base.getType()) |
543 | 3 | : S.Context.getLValueReferenceType(Base.getType())0 ; |
544 | 3 | ExprResult BasePtr = S.BuildCStyleCastExpr( |
545 | 3 | Loc, S.Context.getTrivialTypeSourceInfo(BaseType, Loc), Loc, |
546 | 3 | RecordArg); |
547 | 3 | if (BasePtr.isInvalid() || |
548 | 3 | dumpUnnamedRecord(Base.getType()->getAsRecordDecl(), BasePtr.get(), |
549 | 3 | Depth + 1)) |
550 | 0 | return true; |
551 | 3 | } |
552 | 8 | } |
553 | | |
554 | 20 | Expr *FieldIndentArg = getIndentString(Depth + 1); |
555 | | |
556 | | // Dump each field. |
557 | 80 | for (auto *D : RD->decls()) { |
558 | 80 | auto *IFD = dyn_cast<IndirectFieldDecl>(D); |
559 | 80 | auto *FD = IFD ? IFD->getAnonField()7 : dyn_cast<FieldDecl>(D)73 ; |
560 | 80 | if (!FD || FD->isUnnamedBitfield()56 || FD->isAnonymousStructOrUnion()53 ) |
561 | 31 | continue; |
562 | | |
563 | 49 | llvm::SmallString<20> Format = llvm::StringRef("%s%s %s "); |
564 | 49 | llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg, |
565 | 49 | getTypeString(FD->getType()), |
566 | 49 | getStringLiteral(FD->getName())}; |
567 | | |
568 | 49 | if (FD->isBitField()) { |
569 | 3 | Format += ": %zu "; |
570 | 3 | QualType SizeT = S.Context.getSizeType(); |
571 | 3 | llvm::APInt BitWidth(S.Context.getIntWidth(SizeT), |
572 | 3 | FD->getBitWidthValue(S.Context)); |
573 | 3 | Args.push_back(IntegerLiteral::Create(S.Context, BitWidth, SizeT, Loc)); |
574 | 3 | } |
575 | | |
576 | 49 | Format += "="; |
577 | | |
578 | 49 | ExprResult Field = |
579 | 49 | IFD ? S.BuildAnonymousStructUnionMemberReference( |
580 | 7 | CXXScopeSpec(), Loc, IFD, |
581 | 7 | DeclAccessPair::make(IFD, AS_public), RecordArg, Loc) |
582 | 49 | : S.BuildFieldReferenceExpr( |
583 | 42 | RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD, |
584 | 42 | DeclAccessPair::make(FD, AS_public), |
585 | 42 | DeclarationNameInfo(FD->getDeclName(), Loc)); |
586 | 49 | if (Field.isInvalid()) |
587 | 0 | return true; |
588 | | |
589 | 49 | auto *InnerRD = FD->getType()->getAsRecordDecl(); |
590 | 49 | auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD); |
591 | 49 | if (InnerRD && (6 !InnerCXXRD6 || InnerCXXRD->isAggregate()4 )) { |
592 | | // Recursively print the values of members of aggregate record type. |
593 | 4 | if (callPrintFunction(Format, Args) || |
594 | 4 | dumpRecordValue(InnerRD, Field.get(), FieldIndentArg, Depth + 1)) |
595 | 0 | return true; |
596 | 45 | } else { |
597 | 45 | Format += " "; |
598 | 45 | if (appendFormatSpecifier(FD->getType(), Format)) { |
599 | | // We know how to print this field. |
600 | 39 | Args.push_back(Field.get()); |
601 | 39 | } else { |
602 | | // We don't know how to print this field. Print out its address |
603 | | // with a format specifier that a smart tool will be able to |
604 | | // recognize and treat specially. |
605 | 6 | Format += "*%p"; |
606 | 6 | ExprResult FieldAddr = |
607 | 6 | S.BuildUnaryOp(nullptr, Loc, UO_AddrOf, Field.get()); |
608 | 6 | if (FieldAddr.isInvalid()) |
609 | 0 | return true; |
610 | 6 | Args.push_back(FieldAddr.get()); |
611 | 6 | } |
612 | 45 | Format += "\n"; |
613 | 45 | if (callPrintFunction(Format, Args)) |
614 | 0 | return true; |
615 | 45 | } |
616 | 49 | } |
617 | | |
618 | 20 | return RecordIndent ? callPrintFunction("%s}\n", RecordIndent)7 |
619 | 20 | : callPrintFunction("}\n")13 ; |
620 | 20 | } |
621 | | |
622 | 13 | Expr *buildWrapper() { |
623 | 13 | auto *Wrapper = PseudoObjectExpr::Create(S.Context, TheCall, Actions, |
624 | 13 | PseudoObjectExpr::NoResult); |
625 | 13 | TheCall->setType(Wrapper->getType()); |
626 | 13 | TheCall->setValueKind(Wrapper->getValueKind()); |
627 | 13 | return Wrapper; |
628 | 13 | } |
629 | | }; |
630 | | } // namespace |
631 | | |
632 | 26 | static ExprResult SemaBuiltinDumpStruct(Sema &S, CallExpr *TheCall) { |
633 | 26 | if (checkArgCountAtLeast(S, TheCall, 2)) |
634 | 4 | return ExprError(); |
635 | | |
636 | 22 | ExprResult PtrArgResult = S.DefaultLvalueConversion(TheCall->getArg(0)); |
637 | 22 | if (PtrArgResult.isInvalid()) |
638 | 0 | return ExprError(); |
639 | 22 | TheCall->setArg(0, PtrArgResult.get()); |
640 | | |
641 | | // First argument should be a pointer to a struct. |
642 | 22 | QualType PtrArgType = PtrArgResult.get()->getType(); |
643 | 22 | if (!PtrArgType->isPointerType() || |
644 | 22 | !PtrArgType->getPointeeType()->isRecordType()19 ) { |
645 | 4 | S.Diag(PtrArgResult.get()->getBeginLoc(), |
646 | 4 | diag::err_expected_struct_pointer_argument) |
647 | 4 | << 1 << TheCall->getDirectCallee() << PtrArgType; |
648 | 4 | return ExprError(); |
649 | 4 | } |
650 | 18 | const RecordDecl *RD = PtrArgType->getPointeeType()->getAsRecordDecl(); |
651 | | |
652 | | // Second argument is a callable, but we can't fully validate it until we try |
653 | | // calling it. |
654 | 18 | QualType FnArgType = TheCall->getArg(1)->getType(); |
655 | 18 | if (!FnArgType->isFunctionType() && !FnArgType->isFunctionPointerType()16 && |
656 | 18 | !FnArgType->isBlockPointerType()7 && |
657 | 18 | !(6 S.getLangOpts().CPlusPlus6 && FnArgType->isRecordType()5 )) { |
658 | 6 | auto *BT = FnArgType->getAs<BuiltinType>(); |
659 | 6 | switch (BT ? BT->getKind() : BuiltinType::Void0 ) { |
660 | 0 | case BuiltinType::Dependent: |
661 | 4 | case BuiltinType::Overload: |
662 | 4 | case BuiltinType::BoundMember: |
663 | 4 | case BuiltinType::PseudoObject: |
664 | 4 | case BuiltinType::UnknownAny: |
665 | 4 | case BuiltinType::BuiltinFn: |
666 | | // This might be a callable. |
667 | 4 | break; |
668 | | |
669 | 2 | default: |
670 | 2 | S.Diag(TheCall->getArg(1)->getBeginLoc(), |
671 | 2 | diag::err_expected_callable_argument) |
672 | 2 | << 2 << TheCall->getDirectCallee() << FnArgType; |
673 | 2 | return ExprError(); |
674 | 6 | } |
675 | 6 | } |
676 | | |
677 | 16 | BuiltinDumpStructGenerator Generator(S, TheCall); |
678 | | |
679 | | // Wrap parentheses around the given pointer. This is not necessary for |
680 | | // correct code generation, but it means that when we pretty-print the call |
681 | | // arguments in our diagnostics we will produce '(&s)->n' instead of the |
682 | | // incorrect '&s->n'. |
683 | 16 | Expr *PtrArg = PtrArgResult.get(); |
684 | 16 | PtrArg = new (S.Context) |
685 | 16 | ParenExpr(PtrArg->getBeginLoc(), |
686 | 16 | S.getLocForEndOfToken(PtrArg->getEndLoc()), PtrArg); |
687 | 16 | if (Generator.dumpUnnamedRecord(RD, PtrArg, 0)) |
688 | 3 | return ExprError(); |
689 | | |
690 | 13 | return Generator.buildWrapper(); |
691 | 16 | } |
692 | | |
693 | 16 | static bool SemaBuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) { |
694 | 16 | if (checkArgCount(S, BuiltinCall, 2)) |
695 | 0 | return true; |
696 | | |
697 | 16 | SourceLocation BuiltinLoc = BuiltinCall->getBeginLoc(); |
698 | 16 | Expr *Builtin = BuiltinCall->getCallee()->IgnoreImpCasts(); |
699 | 16 | Expr *Call = BuiltinCall->getArg(0); |
700 | 16 | Expr *Chain = BuiltinCall->getArg(1); |
701 | | |
702 | 16 | if (Call->getStmtClass() != Stmt::CallExprClass) { |
703 | 2 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call) |
704 | 2 | << Call->getSourceRange(); |
705 | 2 | return true; |
706 | 2 | } |
707 | | |
708 | 14 | auto CE = cast<CallExpr>(Call); |
709 | 14 | if (CE->getCallee()->getType()->isBlockPointerType()) { |
710 | 1 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call) |
711 | 1 | << Call->getSourceRange(); |
712 | 1 | return true; |
713 | 1 | } |
714 | | |
715 | 13 | const Decl *TargetDecl = CE->getCalleeDecl(); |
716 | 13 | if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) |
717 | 12 | if (FD->getBuiltinID()) { |
718 | 1 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call) |
719 | 1 | << Call->getSourceRange(); |
720 | 1 | return true; |
721 | 1 | } |
722 | | |
723 | 12 | if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) { |
724 | 1 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call) |
725 | 1 | << Call->getSourceRange(); |
726 | 1 | return true; |
727 | 1 | } |
728 | | |
729 | 11 | ExprResult ChainResult = S.UsualUnaryConversions(Chain); |
730 | 11 | if (ChainResult.isInvalid()) |
731 | 0 | return true; |
732 | 11 | if (!ChainResult.get()->getType()->isPointerType()) { |
733 | 1 | S.Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer) |
734 | 1 | << Chain->getSourceRange(); |
735 | 1 | return true; |
736 | 1 | } |
737 | | |
738 | 10 | QualType ReturnTy = CE->getCallReturnType(S.Context); |
739 | 10 | QualType ArgTys[2] = { ReturnTy, ChainResult.get()->getType() }; |
740 | 10 | QualType BuiltinTy = S.Context.getFunctionType( |
741 | 10 | ReturnTy, ArgTys, FunctionProtoType::ExtProtoInfo()); |
742 | 10 | QualType BuiltinPtrTy = S.Context.getPointerType(BuiltinTy); |
743 | | |
744 | 10 | Builtin = |
745 | 10 | S.ImpCastExprToType(Builtin, BuiltinPtrTy, CK_BuiltinFnToFnPtr).get(); |
746 | | |
747 | 10 | BuiltinCall->setType(CE->getType()); |
748 | 10 | BuiltinCall->setValueKind(CE->getValueKind()); |
749 | 10 | BuiltinCall->setObjectKind(CE->getObjectKind()); |
750 | 10 | BuiltinCall->setCallee(Builtin); |
751 | 10 | BuiltinCall->setArg(1, ChainResult.get()); |
752 | | |
753 | 10 | return false; |
754 | 11 | } |
755 | | |
756 | | namespace { |
757 | | |
758 | | class ScanfDiagnosticFormatHandler |
759 | | : public analyze_format_string::FormatStringHandler { |
760 | | // Accepts the argument index (relative to the first destination index) of the |
761 | | // argument whose size we want. |
762 | | using ComputeSizeFunction = |
763 | | llvm::function_ref<Optional<llvm::APSInt>(unsigned)>; |
764 | | |
765 | | // Accepts the argument index (relative to the first destination index), the |
766 | | // destination size, and the source size). |
767 | | using DiagnoseFunction = |
768 | | llvm::function_ref<void(unsigned, unsigned, unsigned)>; |
769 | | |
770 | | ComputeSizeFunction ComputeSizeArgument; |
771 | | DiagnoseFunction Diagnose; |
772 | | |
773 | | public: |
774 | | ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument, |
775 | | DiagnoseFunction Diagnose) |
776 | 902 | : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {} |
777 | | |
778 | | bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, |
779 | | const char *StartSpecifier, |
780 | 977 | unsigned specifierLen) override { |
781 | 977 | if (!FS.consumesDataArgument()) |
782 | 17 | return true; |
783 | | |
784 | 960 | unsigned NulByte = 0; |
785 | 960 | switch ((FS.getConversionSpecifier().getKind())) { |
786 | 501 | default: |
787 | 501 | return true; |
788 | 374 | case analyze_format_string::ConversionSpecifier::sArg: |
789 | 415 | case analyze_format_string::ConversionSpecifier::ScanListArg: |
790 | 415 | NulByte = 1; |
791 | 415 | break; |
792 | 44 | case analyze_format_string::ConversionSpecifier::cArg: |
793 | 44 | break; |
794 | 960 | } |
795 | | |
796 | 459 | analyze_format_string::OptionalAmount FW = FS.getFieldWidth(); |
797 | 459 | if (FW.getHowSpecified() != |
798 | 459 | analyze_format_string::OptionalAmount::HowSpecified::Constant) |
799 | 142 | return true; |
800 | | |
801 | 317 | unsigned SourceSize = FW.getConstantAmount() + NulByte; |
802 | | |
803 | 317 | Optional<llvm::APSInt> DestSizeAPS = ComputeSizeArgument(FS.getArgIndex()); |
804 | 317 | if (!DestSizeAPS) |
805 | 0 | return true; |
806 | | |
807 | 317 | unsigned DestSize = DestSizeAPS->getZExtValue(); |
808 | | |
809 | 317 | if (DestSize < SourceSize) |
810 | 22 | Diagnose(FS.getArgIndex(), DestSize, SourceSize); |
811 | | |
812 | 317 | return true; |
813 | 317 | } |
814 | | }; |
815 | | |
816 | | class EstimateSizeFormatHandler |
817 | | : public analyze_format_string::FormatStringHandler { |
818 | | size_t Size; |
819 | | |
820 | | public: |
821 | | EstimateSizeFormatHandler(StringRef Format) |
822 | | : Size(std::min(Format.find(0), Format.size()) + |
823 | 345 | 1 /* null byte always written by sprintf */) {} |
824 | | |
825 | | bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, |
826 | | const char *, unsigned SpecifierLen, |
827 | 310 | const TargetInfo &) override { |
828 | | |
829 | 310 | const size_t FieldWidth = computeFieldWidth(FS); |
830 | 310 | const size_t Precision = computePrecision(FS); |
831 | | |
832 | | // The actual format. |
833 | 310 | switch (FS.getConversionSpecifier().getKind()) { |
834 | | // Just a char. |
835 | 16 | case analyze_format_string::ConversionSpecifier::cArg: |
836 | 16 | case analyze_format_string::ConversionSpecifier::CArg: |
837 | 16 | Size += std::max(FieldWidth, (size_t)1); |
838 | 16 | break; |
839 | | // Just an integer. |
840 | 104 | case analyze_format_string::ConversionSpecifier::dArg: |
841 | 104 | case analyze_format_string::ConversionSpecifier::DArg: |
842 | 128 | case analyze_format_string::ConversionSpecifier::iArg: |
843 | 136 | case analyze_format_string::ConversionSpecifier::oArg: |
844 | 136 | case analyze_format_string::ConversionSpecifier::OArg: |
845 | 145 | case analyze_format_string::ConversionSpecifier::uArg: |
846 | 145 | case analyze_format_string::ConversionSpecifier::UArg: |
847 | 169 | case analyze_format_string::ConversionSpecifier::xArg: |
848 | 177 | case analyze_format_string::ConversionSpecifier::XArg: |
849 | 177 | Size += std::max(FieldWidth, Precision); |
850 | 177 | break; |
851 | | |
852 | | // %g style conversion switches between %f or %e style dynamically. |
853 | | // %f always takes less space, so default to it. |
854 | 0 | case analyze_format_string::ConversionSpecifier::gArg: |
855 | 0 | case analyze_format_string::ConversionSpecifier::GArg: |
856 | | |
857 | | // Floating point number in the form '[+]ddd.ddd'. |
858 | 40 | case analyze_format_string::ConversionSpecifier::fArg: |
859 | 40 | case analyze_format_string::ConversionSpecifier::FArg: |
860 | 40 | Size += std::max(FieldWidth, 1 /* integer part */ + |
861 | 40 | (Precision ? 1 + Precision |
862 | 40 | : 00 ) /* period + decimal */); |
863 | 40 | break; |
864 | | |
865 | | // Floating point number in the form '[-]d.ddde[+-]dd'. |
866 | 16 | case analyze_format_string::ConversionSpecifier::eArg: |
867 | 16 | case analyze_format_string::ConversionSpecifier::EArg: |
868 | 16 | Size += |
869 | 16 | std::max(FieldWidth, |
870 | 16 | 1 /* integer part */ + |
871 | 16 | (Precision ? 1 + Precision12 : 04 ) /* period + decimal */ + |
872 | 16 | 1 /* e or E letter */ + 2 /* exponent */); |
873 | 16 | break; |
874 | | |
875 | | // Floating point number in the form '[-]0xh.hhhhp±dd'. |
876 | 0 | case analyze_format_string::ConversionSpecifier::aArg: |
877 | 0 | case analyze_format_string::ConversionSpecifier::AArg: |
878 | 0 | Size += |
879 | 0 | std::max(FieldWidth, |
880 | 0 | 2 /* 0x */ + 1 /* integer part */ + |
881 | 0 | (Precision ? 1 + Precision : 0) /* period + decimal */ + |
882 | 0 | 1 /* p or P letter */ + 1 /* + or - */ + 1 /* value */); |
883 | 0 | break; |
884 | | |
885 | | // Just a string. |
886 | 21 | case analyze_format_string::ConversionSpecifier::sArg: |
887 | 21 | case analyze_format_string::ConversionSpecifier::SArg: |
888 | 21 | Size += FieldWidth; |
889 | 21 | break; |
890 | | |
891 | | // Just a pointer in the form '0xddd'. |
892 | 16 | case analyze_format_string::ConversionSpecifier::pArg: |
893 | 16 | Size += std::max(FieldWidth, 2 /* leading 0x */ + Precision); |
894 | 16 | break; |
895 | | |
896 | | // A plain percent. |
897 | 24 | case analyze_format_string::ConversionSpecifier::PercentArg: |
898 | 24 | Size += 1; |
899 | 24 | break; |
900 | | |
901 | 0 | default: |
902 | 0 | break; |
903 | 310 | } |
904 | | |
905 | 310 | Size += FS.hasPlusPrefix() || FS.hasSpacePrefix()278 ; |
906 | | |
907 | 310 | if (FS.hasAlternativeForm()) { |
908 | 16 | switch (FS.getConversionSpecifier().getKind()) { |
909 | 0 | default: |
910 | 0 | break; |
911 | | // Force a leading '0'. |
912 | 0 | case analyze_format_string::ConversionSpecifier::oArg: |
913 | 0 | Size += 1; |
914 | 0 | break; |
915 | | // Force a leading '0x'. |
916 | 16 | case analyze_format_string::ConversionSpecifier::xArg: |
917 | 16 | case analyze_format_string::ConversionSpecifier::XArg: |
918 | 16 | Size += 2; |
919 | 16 | break; |
920 | | // Force a period '.' before decimal, even if precision is 0. |
921 | 0 | case analyze_format_string::ConversionSpecifier::aArg: |
922 | 0 | case analyze_format_string::ConversionSpecifier::AArg: |
923 | 0 | case analyze_format_string::ConversionSpecifier::eArg: |
924 | 0 | case analyze_format_string::ConversionSpecifier::EArg: |
925 | 0 | case analyze_format_string::ConversionSpecifier::fArg: |
926 | 0 | case analyze_format_string::ConversionSpecifier::FArg: |
927 | 0 | case analyze_format_string::ConversionSpecifier::gArg: |
928 | 0 | case analyze_format_string::ConversionSpecifier::GArg: |
929 | 0 | Size += (Precision ? 0 : 1); |
930 | 0 | break; |
931 | 16 | } |
932 | 16 | } |
933 | 310 | assert(SpecifierLen <= Size && "no underflow"); |
934 | 0 | Size -= SpecifierLen; |
935 | 310 | return true; |
936 | 310 | } |
937 | | |
938 | 345 | size_t getSizeLowerBound() const { return Size; } |
939 | | |
940 | | private: |
941 | 310 | static size_t computeFieldWidth(const analyze_printf::PrintfSpecifier &FS) { |
942 | 310 | const analyze_format_string::OptionalAmount &FW = FS.getFieldWidth(); |
943 | 310 | size_t FieldWidth = 0; |
944 | 310 | if (FW.getHowSpecified() == analyze_format_string::OptionalAmount::Constant) |
945 | 18 | FieldWidth = FW.getConstantAmount(); |
946 | 310 | return FieldWidth; |
947 | 310 | } |
948 | | |
949 | 310 | static size_t computePrecision(const analyze_printf::PrintfSpecifier &FS) { |
950 | 310 | const analyze_format_string::OptionalAmount &FW = FS.getPrecision(); |
951 | 310 | size_t Precision = 0; |
952 | | |
953 | | // See man 3 printf for default precision value based on the specifier. |
954 | 310 | switch (FW.getHowSpecified()) { |
955 | 286 | case analyze_format_string::OptionalAmount::NotSpecified: |
956 | 286 | switch (FS.getConversionSpecifier().getKind()) { |
957 | 61 | default: |
958 | 61 | break; |
959 | 104 | case analyze_format_string::ConversionSpecifier::dArg: // %d |
960 | 104 | case analyze_format_string::ConversionSpecifier::DArg: // %D |
961 | 128 | case analyze_format_string::ConversionSpecifier::iArg: // %i |
962 | 128 | Precision = 1; |
963 | 128 | break; |
964 | 8 | case analyze_format_string::ConversionSpecifier::oArg: // %d |
965 | 8 | case analyze_format_string::ConversionSpecifier::OArg: // %D |
966 | 17 | case analyze_format_string::ConversionSpecifier::uArg: // %d |
967 | 17 | case analyze_format_string::ConversionSpecifier::UArg: // %D |
968 | 41 | case analyze_format_string::ConversionSpecifier::xArg: // %d |
969 | 49 | case analyze_format_string::ConversionSpecifier::XArg: // %D |
970 | 49 | Precision = 1; |
971 | 49 | break; |
972 | 24 | case analyze_format_string::ConversionSpecifier::fArg: // %f |
973 | 24 | case analyze_format_string::ConversionSpecifier::FArg: // %F |
974 | 32 | case analyze_format_string::ConversionSpecifier::eArg: // %e |
975 | 32 | case analyze_format_string::ConversionSpecifier::EArg: // %E |
976 | 32 | case analyze_format_string::ConversionSpecifier::gArg: // %g |
977 | 32 | case analyze_format_string::ConversionSpecifier::GArg: // %G |
978 | 32 | Precision = 6; |
979 | 32 | break; |
980 | 16 | case analyze_format_string::ConversionSpecifier::pArg: // %d |
981 | 16 | Precision = 1; |
982 | 16 | break; |
983 | 286 | } |
984 | 286 | break; |
985 | 286 | case analyze_format_string::OptionalAmount::Constant: |
986 | 24 | Precision = FW.getConstantAmount(); |
987 | 24 | break; |
988 | 0 | default: |
989 | 0 | break; |
990 | 310 | } |
991 | 310 | return Precision; |
992 | 310 | } |
993 | | }; |
994 | | |
995 | | } // namespace |
996 | | |
997 | | void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, |
998 | 3.42M | CallExpr *TheCall) { |
999 | 3.42M | if (TheCall->isValueDependent() || TheCall->isTypeDependent()3.35M || |
1000 | 3.42M | isConstantEvaluated()3.35M ) |
1001 | 122k | return; |
1002 | | |
1003 | 3.30M | bool UseDABAttr = false; |
1004 | 3.30M | const FunctionDecl *UseDecl = FD; |
1005 | | |
1006 | 3.30M | const auto *DABAttr = FD->getAttr<DiagnoseAsBuiltinAttr>(); |
1007 | 3.30M | if (DABAttr) { |
1008 | 12 | UseDecl = DABAttr->getFunction(); |
1009 | 12 | assert(UseDecl && "Missing FunctionDecl in DiagnoseAsBuiltin attribute!"); |
1010 | 0 | UseDABAttr = true; |
1011 | 12 | } |
1012 | | |
1013 | 0 | unsigned BuiltinID = UseDecl->getBuiltinID(/*ConsiderWrappers=*/true); |
1014 | | |
1015 | 3.30M | if (!BuiltinID) |
1016 | 1.61M | return; |
1017 | | |
1018 | 1.68M | const TargetInfo &TI = getASTContext().getTargetInfo(); |
1019 | 1.68M | unsigned SizeTypeWidth = TI.getTypeWidth(TI.getSizeType()); |
1020 | | |
1021 | 1.68M | auto TranslateIndex = [&](unsigned Index) -> Optional<unsigned> { |
1022 | | // If we refer to a diagnose_as_builtin attribute, we need to change the |
1023 | | // argument index to refer to the arguments of the called function. Unless |
1024 | | // the index is out of bounds, which presumably means it's a variadic |
1025 | | // function. |
1026 | 14.0k | if (!UseDABAttr) |
1027 | 14.0k | return Index; |
1028 | 22 | unsigned DABIndices = DABAttr->argIndices_size(); |
1029 | 22 | unsigned NewIndex = Index < DABIndices |
1030 | 22 | ? DABAttr->argIndices_begin()[Index]20 |
1031 | 22 | : Index - DABIndices + FD->getNumParams()2 ; |
1032 | 22 | if (NewIndex >= TheCall->getNumArgs()) |
1033 | 0 | return llvm::None; |
1034 | 22 | return NewIndex; |
1035 | 22 | }; |
1036 | | |
1037 | 1.68M | auto ComputeExplicitObjectSizeArgument = |
1038 | 1.68M | [&](unsigned Index) -> Optional<llvm::APSInt> { |
1039 | 6.96k | Optional<unsigned> IndexOptional = TranslateIndex(Index); |
1040 | 6.96k | if (!IndexOptional) |
1041 | 0 | return llvm::None; |
1042 | 6.96k | unsigned NewIndex = *IndexOptional; |
1043 | 6.96k | Expr::EvalResult Result; |
1044 | 6.96k | Expr *SizeArg = TheCall->getArg(NewIndex); |
1045 | 6.96k | if (!SizeArg->EvaluateAsInt(Result, getASTContext())) |
1046 | 3.12k | return llvm::None; |
1047 | 3.83k | llvm::APSInt Integer = Result.Val.getInt(); |
1048 | 3.83k | Integer.setIsUnsigned(true); |
1049 | 3.83k | return Integer; |
1050 | 6.96k | }; |
1051 | | |
1052 | 1.68M | auto ComputeSizeArgument = [&](unsigned Index) -> Optional<llvm::APSInt> { |
1053 | | // If the parameter has a pass_object_size attribute, then we should use its |
1054 | | // (potentially) more strict checking mode. Otherwise, conservatively assume |
1055 | | // type 0. |
1056 | 6.91k | int BOSType = 0; |
1057 | | // This check can fail for variadic functions. |
1058 | 6.91k | if (Index < FD->getNumParams()) { |
1059 | 6.59k | if (const auto *POS = |
1060 | 6.59k | FD->getParamDecl(Index)->getAttr<PassObjectSizeAttr>()) |
1061 | 2 | BOSType = POS->getType(); |
1062 | 6.59k | } |
1063 | | |
1064 | 6.91k | Optional<unsigned> IndexOptional = TranslateIndex(Index); |
1065 | 6.91k | if (!IndexOptional) |
1066 | 0 | return llvm::None; |
1067 | 6.91k | unsigned NewIndex = *IndexOptional; |
1068 | | |
1069 | 6.91k | const Expr *ObjArg = TheCall->getArg(NewIndex); |
1070 | 6.91k | uint64_t Result; |
1071 | 6.91k | if (!ObjArg->tryEvaluateObjectSize(Result, getASTContext(), BOSType)) |
1072 | 3.55k | return llvm::None; |
1073 | | |
1074 | | // Get the object size in the target's size_t width. |
1075 | 3.35k | return llvm::APSInt::getUnsigned(Result).extOrTrunc(SizeTypeWidth); |
1076 | 6.91k | }; |
1077 | | |
1078 | 1.68M | auto ComputeStrLenArgument = [&](unsigned Index) -> Optional<llvm::APSInt> { |
1079 | 162 | Optional<unsigned> IndexOptional = TranslateIndex(Index); |
1080 | 162 | if (!IndexOptional) |
1081 | 0 | return llvm::None; |
1082 | 162 | unsigned NewIndex = *IndexOptional; |
1083 | | |
1084 | 162 | const Expr *ObjArg = TheCall->getArg(NewIndex); |
1085 | 162 | uint64_t Result; |
1086 | 162 | if (!ObjArg->tryEvaluateStrLen(Result, getASTContext())) |
1087 | 83 | return llvm::None; |
1088 | | // Add 1 for null byte. |
1089 | 79 | return llvm::APSInt::getUnsigned(Result + 1).extOrTrunc(SizeTypeWidth); |
1090 | 162 | }; |
1091 | | |
1092 | 1.68M | Optional<llvm::APSInt> SourceSize; |
1093 | 1.68M | Optional<llvm::APSInt> DestinationSize; |
1094 | 1.68M | unsigned DiagID = 0; |
1095 | 1.68M | bool IsChkVariant = false; |
1096 | | |
1097 | 1.68M | auto GetFunctionName = [&]() { |
1098 | 275 | StringRef FunctionName = getASTContext().BuiltinInfo.getName(BuiltinID); |
1099 | | // Skim off the details of whichever builtin was called to produce a better |
1100 | | // diagnostic, as it's unlikely that the user wrote the __builtin |
1101 | | // explicitly. |
1102 | 275 | if (IsChkVariant) { |
1103 | 112 | FunctionName = FunctionName.drop_front(std::strlen("__builtin___")); |
1104 | 112 | FunctionName = FunctionName.drop_back(std::strlen("_chk")); |
1105 | 163 | } else if (FunctionName.startswith("__builtin_")) { |
1106 | 59 | FunctionName = FunctionName.drop_front(std::strlen("__builtin_")); |
1107 | 59 | } |
1108 | 275 | return FunctionName; |
1109 | 275 | }; |
1110 | | |
1111 | 1.68M | switch (BuiltinID) { |
1112 | 1.67M | default: |
1113 | 1.67M | return; |
1114 | 1.67M | case Builtin::BI__builtin_strcpy: |
1115 | 90 | case Builtin::BIstrcpy: { |
1116 | 90 | DiagID = diag::warn_fortify_strlen_overflow; |
1117 | 90 | SourceSize = ComputeStrLenArgument(1); |
1118 | 90 | DestinationSize = ComputeSizeArgument(0); |
1119 | 90 | break; |
1120 | 28 | } |
1121 | | |
1122 | 72 | case Builtin::BI__builtin___strcpy_chk: { |
1123 | 72 | DiagID = diag::warn_fortify_strlen_overflow; |
1124 | 72 | SourceSize = ComputeStrLenArgument(1); |
1125 | 72 | DestinationSize = ComputeExplicitObjectSizeArgument(2); |
1126 | 72 | IsChkVariant = true; |
1127 | 72 | break; |
1128 | 28 | } |
1129 | | |
1130 | 746 | case Builtin::BIscanf: |
1131 | 807 | case Builtin::BIfscanf: |
1132 | 931 | case Builtin::BIsscanf: { |
1133 | 931 | unsigned FormatIndex = 1; |
1134 | 931 | unsigned DataIndex = 2; |
1135 | 931 | if (BuiltinID == Builtin::BIscanf) { |
1136 | 746 | FormatIndex = 0; |
1137 | 746 | DataIndex = 1; |
1138 | 746 | } |
1139 | | |
1140 | 931 | const auto *FormatExpr = |
1141 | 931 | TheCall->getArg(FormatIndex)->IgnoreParenImpCasts(); |
1142 | | |
1143 | 931 | const auto *Format = dyn_cast<StringLiteral>(FormatExpr); |
1144 | 931 | if (!Format) |
1145 | 29 | return; |
1146 | | |
1147 | 902 | if (!Format->isOrdinary() && !Format->isUTF8()0 ) |
1148 | 0 | return; |
1149 | | |
1150 | 902 | auto Diagnose = [&](unsigned ArgIndex, unsigned DestSize, |
1151 | 902 | unsigned SourceSize) { |
1152 | 22 | DiagID = diag::warn_fortify_scanf_overflow; |
1153 | 22 | unsigned Index = ArgIndex + DataIndex; |
1154 | 22 | StringRef FunctionName = GetFunctionName(); |
1155 | 22 | DiagRuntimeBehavior(TheCall->getArg(Index)->getBeginLoc(), TheCall, |
1156 | 22 | PDiag(DiagID) << FunctionName << (Index + 1) |
1157 | 22 | << DestSize << SourceSize); |
1158 | 22 | }; |
1159 | | |
1160 | 902 | StringRef FormatStrRef = Format->getString(); |
1161 | 902 | auto ShiftedComputeSizeArgument = [&](unsigned Index) { |
1162 | 317 | return ComputeSizeArgument(Index + DataIndex); |
1163 | 317 | }; |
1164 | 902 | ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument, Diagnose); |
1165 | 902 | const char *FormatBytes = FormatStrRef.data(); |
1166 | 902 | const ConstantArrayType *T = |
1167 | 902 | Context.getAsConstantArrayType(Format->getType()); |
1168 | 902 | assert(T && "String literal not of constant array type!"); |
1169 | 0 | size_t TypeSize = T->getSize().getZExtValue(); |
1170 | | |
1171 | | // In case there's a null byte somewhere. |
1172 | 902 | size_t StrLen = |
1173 | 902 | std::min(std::max(TypeSize, size_t(1)) - 1, FormatStrRef.find(0)); |
1174 | | |
1175 | 902 | analyze_format_string::ParseScanfString(H, FormatBytes, |
1176 | 902 | FormatBytes + StrLen, getLangOpts(), |
1177 | 902 | Context.getTargetInfo()); |
1178 | | |
1179 | | // Unlike the other cases, in this one we have already issued the diagnostic |
1180 | | // here, so no need to continue (because unlike the other cases, here the |
1181 | | // diagnostic refers to the argument number). |
1182 | 902 | return; |
1183 | 902 | } |
1184 | | |
1185 | 169 | case Builtin::BIsprintf: |
1186 | 368 | case Builtin::BI__builtin___sprintf_chk: { |
1187 | 368 | size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1169 : 3199 ; |
1188 | 368 | auto *FormatExpr = TheCall->getArg(FormatIndex)->IgnoreParenImpCasts(); |
1189 | | |
1190 | 368 | if (auto *Format = dyn_cast<StringLiteral>(FormatExpr)) { |
1191 | | |
1192 | 345 | if (!Format->isOrdinary() && !Format->isUTF8()0 ) |
1193 | 0 | return; |
1194 | | |
1195 | 345 | StringRef FormatStrRef = Format->getString(); |
1196 | 345 | EstimateSizeFormatHandler H(FormatStrRef); |
1197 | 345 | const char *FormatBytes = FormatStrRef.data(); |
1198 | 345 | const ConstantArrayType *T = |
1199 | 345 | Context.getAsConstantArrayType(Format->getType()); |
1200 | 345 | assert(T && "String literal not of constant array type!"); |
1201 | 0 | size_t TypeSize = T->getSize().getZExtValue(); |
1202 | | |
1203 | | // In case there's a null byte somewhere. |
1204 | 345 | size_t StrLen = |
1205 | 345 | std::min(std::max(TypeSize, size_t(1)) - 1, FormatStrRef.find(0)); |
1206 | 345 | if (!analyze_format_string::ParsePrintfString( |
1207 | 345 | H, FormatBytes, FormatBytes + StrLen, getLangOpts(), |
1208 | 345 | Context.getTargetInfo(), false)) { |
1209 | 345 | DiagID = diag::warn_fortify_source_format_overflow; |
1210 | 345 | SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound()) |
1211 | 345 | .extOrTrunc(SizeTypeWidth); |
1212 | 345 | if (BuiltinID == Builtin::BI__builtin___sprintf_chk) { |
1213 | 195 | DestinationSize = ComputeExplicitObjectSizeArgument(2); |
1214 | 195 | IsChkVariant = true; |
1215 | 195 | } else { |
1216 | 150 | DestinationSize = ComputeSizeArgument(0); |
1217 | 150 | } |
1218 | 345 | break; |
1219 | 345 | } |
1220 | 345 | } |
1221 | 23 | return; |
1222 | 368 | } |
1223 | 37 | case Builtin::BI__builtin___memcpy_chk: |
1224 | 50 | case Builtin::BI__builtin___memmove_chk: |
1225 | 65 | case Builtin::BI__builtin___memset_chk: |
1226 | 68 | case Builtin::BI__builtin___strlcat_chk: |
1227 | 83 | case Builtin::BI__builtin___strlcpy_chk: |
1228 | 103 | case Builtin::BI__builtin___strncat_chk: |
1229 | 119 | case Builtin::BI__builtin___strncpy_chk: |
1230 | 119 | case Builtin::BI__builtin___stpncpy_chk: |
1231 | 126 | case Builtin::BI__builtin___memccpy_chk: |
1232 | 150 | case Builtin::BI__builtin___mempcpy_chk: { |
1233 | 150 | DiagID = diag::warn_builtin_chk_overflow; |
1234 | 150 | SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 2); |
1235 | 150 | DestinationSize = |
1236 | 150 | ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); |
1237 | 150 | IsChkVariant = true; |
1238 | 150 | break; |
1239 | 126 | } |
1240 | | |
1241 | 4 | case Builtin::BI__builtin___snprintf_chk: |
1242 | 19 | case Builtin::BI__builtin___vsnprintf_chk: { |
1243 | 19 | DiagID = diag::warn_builtin_chk_overflow; |
1244 | 19 | SourceSize = ComputeExplicitObjectSizeArgument(1); |
1245 | 19 | DestinationSize = ComputeExplicitObjectSizeArgument(3); |
1246 | 19 | IsChkVariant = true; |
1247 | 19 | break; |
1248 | 4 | } |
1249 | | |
1250 | 94 | case Builtin::BIstrncat: |
1251 | 150 | case Builtin::BI__builtin_strncat: |
1252 | 256 | case Builtin::BIstrncpy: |
1253 | 283 | case Builtin::BI__builtin_strncpy: |
1254 | 283 | case Builtin::BIstpncpy: |
1255 | 291 | case Builtin::BI__builtin_stpncpy: { |
1256 | | // Whether these functions overflow depends on the runtime strlen of the |
1257 | | // string, not just the buffer size, so emitting the "always overflow" |
1258 | | // diagnostic isn't quite right. We should still diagnose passing a buffer |
1259 | | // size larger than the destination buffer though; this is a runtime abort |
1260 | | // in _FORTIFY_SOURCE mode, and is quite suspicious otherwise. |
1261 | 291 | DiagID = diag::warn_fortify_source_size_mismatch; |
1262 | 291 | SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); |
1263 | 291 | DestinationSize = ComputeSizeArgument(0); |
1264 | 291 | break; |
1265 | 283 | } |
1266 | | |
1267 | 1.24k | case Builtin::BImemcpy: |
1268 | 1.47k | case Builtin::BI__builtin_memcpy: |
1269 | 1.58k | case Builtin::BImemmove: |
1270 | 4.27k | case Builtin::BI__builtin_memmove: |
1271 | 4.48k | case Builtin::BImemset: |
1272 | 4.57k | case Builtin::BI__builtin_memset: |
1273 | 4.60k | case Builtin::BImempcpy: |
1274 | 4.62k | case Builtin::BI__builtin_mempcpy: { |
1275 | 4.62k | DiagID = diag::warn_fortify_source_overflow; |
1276 | 4.62k | SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); |
1277 | 4.62k | DestinationSize = ComputeSizeArgument(0); |
1278 | 4.62k | break; |
1279 | 4.60k | } |
1280 | 1.39k | case Builtin::BIsnprintf: |
1281 | 1.41k | case Builtin::BI__builtin_snprintf: |
1282 | 1.43k | case Builtin::BIvsnprintf: |
1283 | 1.44k | case Builtin::BI__builtin_vsnprintf: { |
1284 | 1.44k | DiagID = diag::warn_fortify_source_size_mismatch; |
1285 | 1.44k | SourceSize = ComputeExplicitObjectSizeArgument(1); |
1286 | 1.44k | DestinationSize = ComputeSizeArgument(0); |
1287 | 1.44k | break; |
1288 | 1.43k | } |
1289 | 1.68M | } |
1290 | | |
1291 | 7.03k | if (!SourceSize || !DestinationSize3.87k || |
1292 | 7.03k | llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 03.29k ) |
1293 | 6.77k | return; |
1294 | | |
1295 | 253 | StringRef FunctionName = GetFunctionName(); |
1296 | | |
1297 | 253 | SmallString<16> DestinationStr; |
1298 | 253 | SmallString<16> SourceStr; |
1299 | 253 | DestinationSize->toString(DestinationStr, /*Radix=*/10); |
1300 | 253 | SourceSize->toString(SourceStr, /*Radix=*/10); |
1301 | 253 | DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall, |
1302 | 253 | PDiag(DiagID) |
1303 | 253 | << FunctionName << DestinationStr << SourceStr); |
1304 | 253 | } |
1305 | | |
1306 | | static bool SemaBuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, |
1307 | | Scope::ScopeFlags NeededScopeFlags, |
1308 | 39 | unsigned DiagID) { |
1309 | | // Scopes aren't available during instantiation. Fortunately, builtin |
1310 | | // functions cannot be template args so they cannot be formed through template |
1311 | | // instantiation. Therefore checking once during the parse is sufficient. |
1312 | 39 | if (SemaRef.inTemplateInstantiation()) |
1313 | 0 | return false; |
1314 | | |
1315 | 39 | Scope *S = SemaRef.getCurScope(); |
1316 | 74 | while (S && !S->isSEHExceptScope()62 ) |
1317 | 35 | S = S->getParent(); |
1318 | 39 | if (!S || !(S->getFlags() & NeededScopeFlags)27 ) { |
1319 | 13 | auto *DRE = cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); |
1320 | 13 | SemaRef.Diag(TheCall->getExprLoc(), DiagID) |
1321 | 13 | << DRE->getDecl()->getIdentifier(); |
1322 | 13 | return true; |
1323 | 13 | } |
1324 | | |
1325 | 26 | return false; |
1326 | 39 | } |
1327 | | |
1328 | 671 | static inline bool isBlockPointer(Expr *Arg) { |
1329 | 671 | return Arg->getType()->isBlockPointerType(); |
1330 | 671 | } |
1331 | | |
1332 | | /// OpenCL C v2.0, s6.13.17.2 - Checks that the block parameters are all local |
1333 | | /// void*, which is a requirement of device side enqueue. |
1334 | 439 | static bool checkOpenCLBlockArgs(Sema &S, Expr *BlockArg) { |
1335 | 439 | const BlockPointerType *BPT = |
1336 | 439 | cast<BlockPointerType>(BlockArg->getType().getCanonicalType()); |
1337 | 439 | ArrayRef<QualType> Params = |
1338 | 439 | BPT->getPointeeType()->castAs<FunctionProtoType>()->getParamTypes(); |
1339 | 439 | unsigned ArgCounter = 0; |
1340 | 439 | bool IllegalParams = false; |
1341 | | // Iterate through the block parameters until either one is found that is not |
1342 | | // a local void*, or the block is valid. |
1343 | 439 | for (ArrayRef<QualType>::iterator I = Params.begin(), E = Params.end(); |
1344 | 886 | I != E; ++I, ++ArgCounter447 ) { |
1345 | 447 | if (!(*I)->isPointerType() || !(*I)->getPointeeType()->isVoidType()407 || |
1346 | 447 | (*I)->getPointeeType().getQualifiers().getAddressSpace() != |
1347 | 357 | LangAS::opencl_local) { |
1348 | | // Get the location of the error. If a block literal has been passed |
1349 | | // (BlockExpr) then we can point straight to the offending argument, |
1350 | | // else we just point to the variable reference. |
1351 | 90 | SourceLocation ErrorLoc; |
1352 | 90 | if (isa<BlockExpr>(BlockArg)) { |
1353 | 40 | BlockDecl *BD = cast<BlockExpr>(BlockArg)->getBlockDecl(); |
1354 | 40 | ErrorLoc = BD->getParamDecl(ArgCounter)->getBeginLoc(); |
1355 | 50 | } else if (isa<DeclRefExpr>(BlockArg)) { |
1356 | 50 | ErrorLoc = cast<DeclRefExpr>(BlockArg)->getBeginLoc(); |
1357 | 50 | } |
1358 | 90 | S.Diag(ErrorLoc, |
1359 | 90 | diag::err_opencl_enqueue_kernel_blocks_non_local_void_args); |
1360 | 90 | IllegalParams = true; |
1361 | 90 | } |
1362 | 447 | } |
1363 | | |
1364 | 439 | return IllegalParams; |
1365 | 439 | } |
1366 | | |
1367 | 72 | static bool checkOpenCLSubgroupExt(Sema &S, CallExpr *Call) { |
1368 | | // OpenCL device can support extension but not the feature as extension |
1369 | | // requires subgroup independent forward progress, but subgroup independent |
1370 | | // forward progress is optional in OpenCL C 3.0 __opencl_c_subgroups feature. |
1371 | 72 | if (!S.getOpenCLOptions().isSupported("cl_khr_subgroups", S.getLangOpts()) && |
1372 | 72 | !S.getOpenCLOptions().isSupported("__opencl_c_subgroups", |
1373 | 4 | S.getLangOpts())) { |
1374 | 4 | S.Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension) |
1375 | 4 | << 1 << Call->getDirectCallee() |
1376 | 4 | << "cl_khr_subgroups or __opencl_c_subgroups"; |
1377 | 4 | return true; |
1378 | 4 | } |
1379 | 68 | return false; |
1380 | 72 | } |
1381 | | |
1382 | 64 | static bool SemaOpenCLBuiltinNDRangeAndBlock(Sema &S, CallExpr *TheCall) { |
1383 | 64 | if (checkArgCount(S, TheCall, 2)) |
1384 | 0 | return true; |
1385 | | |
1386 | 64 | if (checkOpenCLSubgroupExt(S, TheCall)) |
1387 | 4 | return true; |
1388 | | |
1389 | | // First argument is an ndrange_t type. |
1390 | 60 | Expr *NDRangeArg = TheCall->getArg(0); |
1391 | 60 | if (NDRangeArg->getType().getUnqualifiedType().getAsString() != "ndrange_t") { |
1392 | 16 | S.Diag(NDRangeArg->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
1393 | 16 | << TheCall->getDirectCallee() << "'ndrange_t'"; |
1394 | 16 | return true; |
1395 | 16 | } |
1396 | | |
1397 | 44 | Expr *BlockArg = TheCall->getArg(1); |
1398 | 44 | if (!isBlockPointer(BlockArg)) { |
1399 | 16 | S.Diag(BlockArg->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
1400 | 16 | << TheCall->getDirectCallee() << "block"; |
1401 | 16 | return true; |
1402 | 16 | } |
1403 | 28 | return checkOpenCLBlockArgs(S, BlockArg); |
1404 | 44 | } |
1405 | | |
1406 | | /// OpenCL C v2.0, s6.13.17.6 - Check the argument to the |
1407 | | /// get_kernel_work_group_size |
1408 | | /// and get_kernel_preferred_work_group_size_multiple builtin functions. |
1409 | 232 | static bool SemaOpenCLBuiltinKernelWorkGroupSize(Sema &S, CallExpr *TheCall) { |
1410 | 232 | if (checkArgCount(S, TheCall, 1)) |
1411 | 40 | return true; |
1412 | | |
1413 | 192 | Expr *BlockArg = TheCall->getArg(0); |
1414 | 192 | if (!isBlockPointer(BlockArg)) { |
1415 | 20 | S.Diag(BlockArg->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
1416 | 20 | << TheCall->getDirectCallee() << "block"; |
1417 | 20 | return true; |
1418 | 20 | } |
1419 | 172 | return checkOpenCLBlockArgs(S, BlockArg); |
1420 | 192 | } |
1421 | | |
1422 | | /// Diagnose integer type and any valid implicit conversion to it. |
1423 | | static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, |
1424 | | const QualType &IntType); |
1425 | | |
1426 | | static bool checkOpenCLEnqueueLocalSizeArgs(Sema &S, CallExpr *TheCall, |
1427 | 147 | unsigned Start, unsigned End) { |
1428 | 147 | bool IllegalParams = false; |
1429 | 396 | for (unsigned I = Start; I <= End; ++I249 ) |
1430 | 249 | IllegalParams |= checkOpenCLEnqueueIntType(S, TheCall->getArg(I), |
1431 | 249 | S.Context.getSizeType()); |
1432 | 147 | return IllegalParams; |
1433 | 147 | } |
1434 | | |
1435 | | /// OpenCL v2.0, s6.13.17.1 - Check that sizes are provided for all |
1436 | | /// 'local void*' parameter of passed block. |
1437 | | static bool checkOpenCLEnqueueVariadicArgs(Sema &S, CallExpr *TheCall, |
1438 | | Expr *BlockArg, |
1439 | 167 | unsigned NumNonVarArgs) { |
1440 | 167 | const BlockPointerType *BPT = |
1441 | 167 | cast<BlockPointerType>(BlockArg->getType().getCanonicalType()); |
1442 | 167 | unsigned NumBlockParams = |
1443 | 167 | BPT->getPointeeType()->castAs<FunctionProtoType>()->getNumParams(); |
1444 | 167 | unsigned TotalNumArgs = TheCall->getNumArgs(); |
1445 | | |
1446 | | // For each argument passed to the block, a corresponding uint needs to |
1447 | | // be passed to describe the size of the local memory. |
1448 | 167 | if (TotalNumArgs != NumBlockParams + NumNonVarArgs) { |
1449 | 20 | S.Diag(TheCall->getBeginLoc(), |
1450 | 20 | diag::err_opencl_enqueue_kernel_local_size_args); |
1451 | 20 | return true; |
1452 | 20 | } |
1453 | | |
1454 | | // Check that the sizes of the local memory are specified by integers. |
1455 | 147 | return checkOpenCLEnqueueLocalSizeArgs(S, TheCall, NumNonVarArgs, |
1456 | 147 | TotalNumArgs - 1); |
1457 | 167 | } |
1458 | | |
1459 | | /// OpenCL C v2.0, s6.13.17 - Enqueue kernel function contains four different |
1460 | | /// overload formats specified in Table 6.13.17.1. |
1461 | | /// int enqueue_kernel(queue_t queue, |
1462 | | /// kernel_enqueue_flags_t flags, |
1463 | | /// const ndrange_t ndrange, |
1464 | | /// void (^block)(void)) |
1465 | | /// int enqueue_kernel(queue_t queue, |
1466 | | /// kernel_enqueue_flags_t flags, |
1467 | | /// const ndrange_t ndrange, |
1468 | | /// uint num_events_in_wait_list, |
1469 | | /// clk_event_t *event_wait_list, |
1470 | | /// clk_event_t *event_ret, |
1471 | | /// void (^block)(void)) |
1472 | | /// int enqueue_kernel(queue_t queue, |
1473 | | /// kernel_enqueue_flags_t flags, |
1474 | | /// const ndrange_t ndrange, |
1475 | | /// void (^block)(local void*, ...), |
1476 | | /// uint size0, ...) |
1477 | | /// int enqueue_kernel(queue_t queue, |
1478 | | /// kernel_enqueue_flags_t flags, |
1479 | | /// const ndrange_t ndrange, |
1480 | | /// uint num_events_in_wait_list, |
1481 | | /// clk_event_t *event_wait_list, |
1482 | | /// clk_event_t *event_ret, |
1483 | | /// void (^block)(local void*, ...), |
1484 | | /// uint size0, ...) |
1485 | 361 | static bool SemaOpenCLBuiltinEnqueueKernel(Sema &S, CallExpr *TheCall) { |
1486 | 361 | unsigned NumArgs = TheCall->getNumArgs(); |
1487 | | |
1488 | 361 | if (NumArgs < 4) { |
1489 | 10 | S.Diag(TheCall->getBeginLoc(), |
1490 | 10 | diag::err_typecheck_call_too_few_args_at_least) |
1491 | 10 | << 0 << 4 << NumArgs; |
1492 | 10 | return true; |
1493 | 10 | } |
1494 | | |
1495 | 351 | Expr *Arg0 = TheCall->getArg(0); |
1496 | 351 | Expr *Arg1 = TheCall->getArg(1); |
1497 | 351 | Expr *Arg2 = TheCall->getArg(2); |
1498 | 351 | Expr *Arg3 = TheCall->getArg(3); |
1499 | | |
1500 | | // First argument always needs to be a queue_t type. |
1501 | 351 | if (!Arg0->getType()->isQueueT()) { |
1502 | 10 | S.Diag(TheCall->getArg(0)->getBeginLoc(), |
1503 | 10 | diag::err_opencl_builtin_expected_type) |
1504 | 10 | << TheCall->getDirectCallee() << S.Context.OCLQueueTy; |
1505 | 10 | return true; |
1506 | 10 | } |
1507 | | |
1508 | | // Second argument always needs to be a kernel_enqueue_flags_t enum value. |
1509 | 341 | if (!Arg1->getType()->isIntegerType()) { |
1510 | 10 | S.Diag(TheCall->getArg(1)->getBeginLoc(), |
1511 | 10 | diag::err_opencl_builtin_expected_type) |
1512 | 10 | << TheCall->getDirectCallee() << "'kernel_enqueue_flags_t' (i.e. uint)"; |
1513 | 10 | return true; |
1514 | 10 | } |
1515 | | |
1516 | | // Third argument is always an ndrange_t type. |
1517 | 331 | if (Arg2->getType().getUnqualifiedType().getAsString() != "ndrange_t") { |
1518 | 10 | S.Diag(TheCall->getArg(2)->getBeginLoc(), |
1519 | 10 | diag::err_opencl_builtin_expected_type) |
1520 | 10 | << TheCall->getDirectCallee() << "'ndrange_t'"; |
1521 | 10 | return true; |
1522 | 10 | } |
1523 | | |
1524 | | // With four arguments, there is only one form that the function could be |
1525 | | // called in: no events and no variable arguments. |
1526 | 321 | if (NumArgs == 4) { |
1527 | | // check that the last argument is the right block type. |
1528 | 52 | if (!isBlockPointer(Arg3)) { |
1529 | 10 | S.Diag(Arg3->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
1530 | 10 | << TheCall->getDirectCallee() << "block"; |
1531 | 10 | return true; |
1532 | 10 | } |
1533 | | // we have a block type, check the prototype |
1534 | 42 | const BlockPointerType *BPT = |
1535 | 42 | cast<BlockPointerType>(Arg3->getType().getCanonicalType()); |
1536 | 42 | if (BPT->getPointeeType()->castAs<FunctionProtoType>()->getNumParams() > 0) { |
1537 | 10 | S.Diag(Arg3->getBeginLoc(), |
1538 | 10 | diag::err_opencl_enqueue_kernel_blocks_no_args); |
1539 | 10 | return true; |
1540 | 10 | } |
1541 | 32 | return false; |
1542 | 42 | } |
1543 | | // we can have block + varargs. |
1544 | 269 | if (isBlockPointer(Arg3)) |
1545 | 135 | return (checkOpenCLBlockArgs(S, Arg3) || |
1546 | 135 | checkOpenCLEnqueueVariadicArgs(S, TheCall, Arg3, 4)125 ); |
1547 | | // last two cases with either exactly 7 args or 7 args and varargs. |
1548 | 134 | if (NumArgs >= 7) { |
1549 | | // check common block argument. |
1550 | 114 | Expr *Arg6 = TheCall->getArg(6); |
1551 | 114 | if (!isBlockPointer(Arg6)) { |
1552 | 10 | S.Diag(Arg6->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
1553 | 10 | << TheCall->getDirectCallee() << "block"; |
1554 | 10 | return true; |
1555 | 10 | } |
1556 | 104 | if (checkOpenCLBlockArgs(S, Arg6)) |
1557 | 0 | return true; |
1558 | | |
1559 | | // Forth argument has to be any integer type. |
1560 | 104 | if (!Arg3->getType()->isIntegerType()) { |
1561 | 10 | S.Diag(TheCall->getArg(3)->getBeginLoc(), |
1562 | 10 | diag::err_opencl_builtin_expected_type) |
1563 | 10 | << TheCall->getDirectCallee() << "integer"; |
1564 | 10 | return true; |
1565 | 10 | } |
1566 | | // check remaining common arguments. |
1567 | 94 | Expr *Arg4 = TheCall->getArg(4); |
1568 | 94 | Expr *Arg5 = TheCall->getArg(5); |
1569 | | |
1570 | | // Fifth argument is always passed as a pointer to clk_event_t. |
1571 | 94 | if (!Arg4->isNullPointerConstant(S.Context, |
1572 | 94 | Expr::NPC_ValueDependentIsNotNull) && |
1573 | 94 | !Arg4->getType()->getPointeeOrArrayElementType()->isClkEventT()68 ) { |
1574 | 10 | S.Diag(TheCall->getArg(4)->getBeginLoc(), |
1575 | 10 | diag::err_opencl_builtin_expected_type) |
1576 | 10 | << TheCall->getDirectCallee() |
1577 | 10 | << S.Context.getPointerType(S.Context.OCLClkEventTy); |
1578 | 10 | return true; |
1579 | 10 | } |
1580 | | |
1581 | | // Sixth argument is always passed as a pointer to clk_event_t. |
1582 | 84 | if (!Arg5->isNullPointerConstant(S.Context, |
1583 | 84 | Expr::NPC_ValueDependentIsNotNull) && |
1584 | 84 | !(58 Arg5->getType()->isPointerType()58 && |
1585 | 58 | Arg5->getType()->getPointeeType()->isClkEventT())) { |
1586 | 10 | S.Diag(TheCall->getArg(5)->getBeginLoc(), |
1587 | 10 | diag::err_opencl_builtin_expected_type) |
1588 | 10 | << TheCall->getDirectCallee() |
1589 | 10 | << S.Context.getPointerType(S.Context.OCLClkEventTy); |
1590 | 10 | return true; |
1591 | 10 | } |
1592 | | |
1593 | 74 | if (NumArgs == 7) |
1594 | 32 | return false; |
1595 | | |
1596 | 42 | return checkOpenCLEnqueueVariadicArgs(S, TheCall, Arg6, 7); |
1597 | 74 | } |
1598 | | |
1599 | | // None of the specific case has been detected, give generic error |
1600 | 20 | S.Diag(TheCall->getBeginLoc(), |
1601 | 20 | diag::err_opencl_enqueue_kernel_incorrect_args); |
1602 | 20 | return true; |
1603 | 134 | } |
1604 | | |
1605 | | /// Returns OpenCL access qual. |
1606 | 58 | static OpenCLAccessAttr *getOpenCLArgAccess(const Decl *D) { |
1607 | 58 | return D->getAttr<OpenCLAccessAttr>(); |
1608 | 58 | } |
1609 | | |
1610 | | /// Returns true if pipe element type is different from the pointer. |
1611 | 64 | static bool checkOpenCLPipeArg(Sema &S, CallExpr *Call) { |
1612 | 64 | const Expr *Arg0 = Call->getArg(0); |
1613 | | // First argument type should always be pipe. |
1614 | 64 | if (!Arg0->getType()->isPipeType()) { |
1615 | 6 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg) |
1616 | 6 | << Call->getDirectCallee() << Arg0->getSourceRange(); |
1617 | 6 | return true; |
1618 | 6 | } |
1619 | 58 | OpenCLAccessAttr *AccessQual = |
1620 | 58 | getOpenCLArgAccess(cast<DeclRefExpr>(Arg0)->getDecl()); |
1621 | | // Validates the access qualifier is compatible with the call. |
1622 | | // OpenCL v2.0 s6.13.16 - The access qualifiers for pipe should only be |
1623 | | // read_only and write_only, and assumed to be read_only if no qualifier is |
1624 | | // specified. |
1625 | 58 | switch (Call->getDirectCallee()->getBuiltinID()) { |
1626 | 21 | case Builtin::BIread_pipe: |
1627 | 26 | case Builtin::BIreserve_read_pipe: |
1628 | 28 | case Builtin::BIcommit_read_pipe: |
1629 | 29 | case Builtin::BIwork_group_reserve_read_pipe: |
1630 | 31 | case Builtin::BIsub_group_reserve_read_pipe: |
1631 | 33 | case Builtin::BIwork_group_commit_read_pipe: |
1632 | 35 | case Builtin::BIsub_group_commit_read_pipe: |
1633 | 35 | if (!(!AccessQual || AccessQual->isReadOnly())) { |
1634 | 4 | S.Diag(Arg0->getBeginLoc(), |
1635 | 4 | diag::err_opencl_builtin_pipe_invalid_access_modifier) |
1636 | 4 | << "read_only" << Arg0->getSourceRange(); |
1637 | 4 | return true; |
1638 | 4 | } |
1639 | 31 | break; |
1640 | 31 | case Builtin::BIwrite_pipe: |
1641 | 14 | case Builtin::BIreserve_write_pipe: |
1642 | 16 | case Builtin::BIcommit_write_pipe: |
1643 | 17 | case Builtin::BIwork_group_reserve_write_pipe: |
1644 | 19 | case Builtin::BIsub_group_reserve_write_pipe: |
1645 | 21 | case Builtin::BIwork_group_commit_write_pipe: |
1646 | 23 | case Builtin::BIsub_group_commit_write_pipe: |
1647 | 23 | if (!(AccessQual && AccessQual->isWriteOnly())) { |
1648 | 4 | S.Diag(Arg0->getBeginLoc(), |
1649 | 4 | diag::err_opencl_builtin_pipe_invalid_access_modifier) |
1650 | 4 | << "write_only" << Arg0->getSourceRange(); |
1651 | 4 | return true; |
1652 | 4 | } |
1653 | 19 | break; |
1654 | 19 | default: |
1655 | 0 | break; |
1656 | 58 | } |
1657 | 50 | return false; |
1658 | 58 | } |
1659 | | |
1660 | | /// Returns true if pipe element type is different from the pointer. |
1661 | 24 | static bool checkOpenCLPipePacketType(Sema &S, CallExpr *Call, unsigned Idx) { |
1662 | 24 | const Expr *Arg0 = Call->getArg(0); |
1663 | 24 | const Expr *ArgIdx = Call->getArg(Idx); |
1664 | 24 | const PipeType *PipeTy = cast<PipeType>(Arg0->getType()); |
1665 | 24 | const QualType EltTy = PipeTy->getElementType(); |
1666 | 24 | const PointerType *ArgTy = ArgIdx->getType()->getAs<PointerType>(); |
1667 | | // The Idx argument should be a pointer and the type of the pointer and |
1668 | | // the type of pipe element should also be the same. |
1669 | 24 | if (!ArgTy || |
1670 | 24 | !S.Context.hasSameType( |
1671 | 22 | EltTy, ArgTy->getPointeeType()->getCanonicalTypeInternal())) { |
1672 | 2 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
1673 | 2 | << Call->getDirectCallee() << S.Context.getPointerType(EltTy) |
1674 | 2 | << ArgIdx->getType() << ArgIdx->getSourceRange(); |
1675 | 2 | return true; |
1676 | 2 | } |
1677 | 22 | return false; |
1678 | 24 | } |
1679 | | |
1680 | | // Performs semantic analysis for the read/write_pipe call. |
1681 | | // \param S Reference to the semantic analyzer. |
1682 | | // \param Call A pointer to the builtin call. |
1683 | | // \return True if a semantic error has been found, false otherwise. |
1684 | 36 | static bool SemaBuiltinRWPipe(Sema &S, CallExpr *Call) { |
1685 | | // OpenCL v2.0 s6.13.16.2 - The built-in read/write |
1686 | | // functions have two forms. |
1687 | 36 | switch (Call->getNumArgs()) { |
1688 | 24 | case 2: |
1689 | 24 | if (checkOpenCLPipeArg(S, Call)) |
1690 | 4 | return true; |
1691 | | // The call with 2 arguments should be |
1692 | | // read/write_pipe(pipe T, T*). |
1693 | | // Check packet type T. |
1694 | 20 | if (checkOpenCLPipePacketType(S, Call, 1)) |
1695 | 2 | return true; |
1696 | 18 | break; |
1697 | | |
1698 | 18 | case 4: { |
1699 | 10 | if (checkOpenCLPipeArg(S, Call)) |
1700 | 2 | return true; |
1701 | | // The call with 4 arguments should be |
1702 | | // read/write_pipe(pipe T, reserve_id_t, uint, T*). |
1703 | | // Check reserve_id_t. |
1704 | 8 | if (!Call->getArg(1)->getType()->isReserveIDT()) { |
1705 | 2 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
1706 | 2 | << Call->getDirectCallee() << S.Context.OCLReserveIDTy |
1707 | 2 | << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange(); |
1708 | 2 | return true; |
1709 | 2 | } |
1710 | | |
1711 | | // Check the index. |
1712 | 6 | const Expr *Arg2 = Call->getArg(2); |
1713 | 6 | if (!Arg2->getType()->isIntegerType() && |
1714 | 6 | !Arg2->getType()->isUnsignedIntegerType()2 ) { |
1715 | 2 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
1716 | 2 | << Call->getDirectCallee() << S.Context.UnsignedIntTy |
1717 | 2 | << Arg2->getType() << Arg2->getSourceRange(); |
1718 | 2 | return true; |
1719 | 2 | } |
1720 | | |
1721 | | // Check packet type T. |
1722 | 4 | if (checkOpenCLPipePacketType(S, Call, 3)) |
1723 | 0 | return true; |
1724 | 4 | } break; |
1725 | 4 | default: |
1726 | 2 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_arg_num) |
1727 | 2 | << Call->getDirectCallee() << Call->getSourceRange(); |
1728 | 2 | return true; |
1729 | 36 | } |
1730 | | |
1731 | 22 | return false; |
1732 | 36 | } |
1733 | | |
1734 | | // Performs a semantic analysis on the {work_group_/sub_group_ |
1735 | | // /_}reserve_{read/write}_pipe |
1736 | | // \param S Reference to the semantic analyzer. |
1737 | | // \param Call The call to the builtin function to be analyzed. |
1738 | | // \return True if a semantic error was found, false otherwise. |
1739 | 16 | static bool SemaBuiltinReserveRWPipe(Sema &S, CallExpr *Call) { |
1740 | 16 | if (checkArgCount(S, Call, 2)) |
1741 | 0 | return true; |
1742 | | |
1743 | 16 | if (checkOpenCLPipeArg(S, Call)) |
1744 | 4 | return true; |
1745 | | |
1746 | | // Check the reserve size. |
1747 | 12 | if (!Call->getArg(1)->getType()->isIntegerType() && |
1748 | 12 | !Call->getArg(1)->getType()->isUnsignedIntegerType()2 ) { |
1749 | 2 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
1750 | 2 | << Call->getDirectCallee() << S.Context.UnsignedIntTy |
1751 | 2 | << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange(); |
1752 | 2 | return true; |
1753 | 2 | } |
1754 | | |
1755 | | // Since return type of reserve_read/write_pipe built-in function is |
1756 | | // reserve_id_t, which is not defined in the builtin def file , we used int |
1757 | | // as return type and need to override the return type of these functions. |
1758 | 10 | Call->setType(S.Context.OCLReserveIDTy); |
1759 | | |
1760 | 10 | return false; |
1761 | 12 | } |
1762 | | |
1763 | | // Performs a semantic analysis on {work_group_/sub_group_ |
1764 | | // /_}commit_{read/write}_pipe |
1765 | | // \param S Reference to the semantic analyzer. |
1766 | | // \param Call The call to the builtin function to be analyzed. |
1767 | | // \return True if a semantic error was found, false otherwise. |
1768 | 14 | static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) { |
1769 | 14 | if (checkArgCount(S, Call, 2)) |
1770 | 0 | return true; |
1771 | | |
1772 | 14 | if (checkOpenCLPipeArg(S, Call)) |
1773 | 4 | return true; |
1774 | | |
1775 | | // Check reserve_id_t. |
1776 | 10 | if (!Call->getArg(1)->getType()->isReserveIDT()) { |
1777 | 2 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
1778 | 2 | << Call->getDirectCallee() << S.Context.OCLReserveIDTy |
1779 | 2 | << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange(); |
1780 | 2 | return true; |
1781 | 2 | } |
1782 | | |
1783 | 8 | return false; |
1784 | 10 | } |
1785 | | |
1786 | | // Performs a semantic analysis on the call to built-in Pipe |
1787 | | // Query Functions. |
1788 | | // \param S Reference to the semantic analyzer. |
1789 | | // \param Call The call to the builtin function to be analyzed. |
1790 | | // \return True if a semantic error was found, false otherwise. |
1791 | 10 | static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) { |
1792 | 10 | if (checkArgCount(S, Call, 1)) |
1793 | 0 | return true; |
1794 | | |
1795 | 10 | if (!Call->getArg(0)->getType()->isPipeType()) { |
1796 | 2 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg) |
1797 | 2 | << Call->getDirectCallee() << Call->getArg(0)->getSourceRange(); |
1798 | 2 | return true; |
1799 | 2 | } |
1800 | | |
1801 | 8 | return false; |
1802 | 10 | } |
1803 | | |
1804 | | // OpenCL v2.0 s6.13.9 - Address space qualifier functions. |
1805 | | // Performs semantic analysis for the to_global/local/private call. |
1806 | | // \param S Reference to the semantic analyzer. |
1807 | | // \param BuiltinID ID of the builtin function. |
1808 | | // \param Call A pointer to the builtin call. |
1809 | | // \return True if a semantic error has been found, false otherwise. |
1810 | | static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID, |
1811 | 75 | CallExpr *Call) { |
1812 | 75 | if (checkArgCount(S, Call, 1)) |
1813 | 2 | return true; |
1814 | | |
1815 | 73 | auto RT = Call->getArg(0)->getType(); |
1816 | 73 | if (!RT->isPointerType() || RT->getPointeeType() |
1817 | 71 | .getAddressSpace() == LangAS::opencl_constant) { |
1818 | 6 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_to_addr_invalid_arg) |
1819 | 6 | << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange(); |
1820 | 6 | return true; |
1821 | 6 | } |
1822 | | |
1823 | 67 | if (RT->getPointeeType().getAddressSpace() != LangAS::opencl_generic) { |
1824 | 52 | S.Diag(Call->getArg(0)->getBeginLoc(), |
1825 | 52 | diag::warn_opencl_generic_address_space_arg) |
1826 | 52 | << Call->getDirectCallee()->getNameInfo().getAsString() |
1827 | 52 | << Call->getArg(0)->getSourceRange(); |
1828 | 52 | } |
1829 | | |
1830 | 67 | RT = RT->getPointeeType(); |
1831 | 67 | auto Qual = RT.getQualifiers(); |
1832 | 67 | switch (BuiltinID) { |
1833 | 29 | case Builtin::BIto_global: |
1834 | 29 | Qual.setAddressSpace(LangAS::opencl_global); |
1835 | 29 | break; |
1836 | 19 | case Builtin::BIto_local: |
1837 | 19 | Qual.setAddressSpace(LangAS::opencl_local); |
1838 | 19 | break; |
1839 | 19 | case Builtin::BIto_private: |
1840 | 19 | Qual.setAddressSpace(LangAS::opencl_private); |
1841 | 19 | break; |
1842 | 0 | default: |
1843 | 0 | llvm_unreachable("Invalid builtin function"); |
1844 | 67 | } |
1845 | 67 | Call->setType(S.Context.getPointerType(S.Context.getQualifiedType( |
1846 | 67 | RT.getUnqualifiedType(), Qual))); |
1847 | | |
1848 | 67 | return false; |
1849 | 67 | } |
1850 | | |
1851 | 120 | static ExprResult SemaBuiltinLaunder(Sema &S, CallExpr *TheCall) { |
1852 | 120 | if (checkArgCount(S, TheCall, 1)) |
1853 | 2 | return ExprError(); |
1854 | | |
1855 | | // Compute __builtin_launder's parameter type from the argument. |
1856 | | // The parameter type is: |
1857 | | // * The type of the argument if it's not an array or function type, |
1858 | | // Otherwise, |
1859 | | // * The decayed argument type. |
1860 | 118 | QualType ParamTy = [&]() { |
1861 | 118 | QualType ArgTy = TheCall->getArg(0)->getType(); |
1862 | 118 | if (const ArrayType *Ty = ArgTy->getAsArrayTypeUnsafe()) |
1863 | 14 | return S.Context.getPointerType(Ty->getElementType()); |
1864 | 104 | if (ArgTy->isFunctionType()) { |
1865 | 2 | return S.Context.getPointerType(ArgTy); |
1866 | 2 | } |
1867 | 102 | return ArgTy; |
1868 | 104 | }(); |
1869 | | |
1870 | 118 | TheCall->setType(ParamTy); |
1871 | | |
1872 | 118 | auto DiagSelect = [&]() -> llvm::Optional<unsigned> { |
1873 | 118 | if (!ParamTy->isPointerType()) |
1874 | 11 | return 0; |
1875 | 107 | if (ParamTy->isFunctionPointerType()) |
1876 | 5 | return 1; |
1877 | 102 | if (ParamTy->isVoidPointerType()) |
1878 | 6 | return 2; |
1879 | 96 | return llvm::Optional<unsigned>{}; |
1880 | 102 | }(); |
1881 | 118 | if (DiagSelect) { |
1882 | 22 | S.Diag(TheCall->getBeginLoc(), diag::err_builtin_launder_invalid_arg) |
1883 | 22 | << DiagSelect.value() << TheCall->getSourceRange(); |
1884 | 22 | return ExprError(); |
1885 | 22 | } |
1886 | | |
1887 | | // We either have an incomplete class type, or we have a class template |
1888 | | // whose instantiation has not been forced. Example: |
1889 | | // |
1890 | | // template <class T> struct Foo { T value; }; |
1891 | | // Foo<int> *p = nullptr; |
1892 | | // auto *d = __builtin_launder(p); |
1893 | 96 | if (S.RequireCompleteType(TheCall->getBeginLoc(), ParamTy->getPointeeType(), |
1894 | 96 | diag::err_incomplete_type)) |
1895 | 2 | return ExprError(); |
1896 | | |
1897 | 94 | assert(ParamTy->getPointeeType()->isObjectType() && |
1898 | 94 | "Unhandled non-object pointer case"); |
1899 | | |
1900 | 0 | InitializedEntity Entity = |
1901 | 94 | InitializedEntity::InitializeParameter(S.Context, ParamTy, false); |
1902 | 94 | ExprResult Arg = |
1903 | 94 | S.PerformCopyInitialization(Entity, SourceLocation(), TheCall->getArg(0)); |
1904 | 94 | if (Arg.isInvalid()) |
1905 | 0 | return ExprError(); |
1906 | 94 | TheCall->setArg(0, Arg.get()); |
1907 | | |
1908 | 94 | return TheCall; |
1909 | 94 | } |
1910 | | |
1911 | | // Emit an error and return true if the current object format type is in the |
1912 | | // list of unsupported types. |
1913 | | static bool CheckBuiltinTargetNotInUnsupported( |
1914 | | Sema &S, unsigned BuiltinID, CallExpr *TheCall, |
1915 | 396 | ArrayRef<llvm::Triple::ObjectFormatType> UnsupportedObjectFormatTypes) { |
1916 | 396 | llvm::Triple::ObjectFormatType CurObjFormat = |
1917 | 396 | S.getASTContext().getTargetInfo().getTriple().getObjectFormat(); |
1918 | 396 | if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) { |
1919 | 0 | S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) |
1920 | 0 | << TheCall->getSourceRange(); |
1921 | 0 | return true; |
1922 | 0 | } |
1923 | 396 | return false; |
1924 | 396 | } |
1925 | | |
1926 | | // Emit an error and return true if the current architecture is not in the list |
1927 | | // of supported architectures. |
1928 | | static bool |
1929 | | CheckBuiltinTargetInSupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, |
1930 | 90 | ArrayRef<llvm::Triple::ArchType> SupportedArchs) { |
1931 | 90 | llvm::Triple::ArchType CurArch = |
1932 | 90 | S.getASTContext().getTargetInfo().getTriple().getArch(); |
1933 | 90 | if (llvm::is_contained(SupportedArchs, CurArch)) |
1934 | 72 | return false; |
1935 | 18 | S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) |
1936 | 18 | << TheCall->getSourceRange(); |
1937 | 18 | return true; |
1938 | 90 | } |
1939 | | |
1940 | | static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, |
1941 | | SourceLocation CallSiteLoc); |
1942 | | |
1943 | | bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
1944 | 1.49M | CallExpr *TheCall) { |
1945 | 1.49M | switch (TI.getTriple().getArch()) { |
1946 | 2.87k | default: |
1947 | | // Some builtins don't require additional checking, so just consider these |
1948 | | // acceptable. |
1949 | 2.87k | return false; |
1950 | 19.6k | case llvm::Triple::arm: |
1951 | 20.7k | case llvm::Triple::armeb: |
1952 | 38.3k | case llvm::Triple::thumb: |
1953 | 38.6k | case llvm::Triple::thumbeb: |
1954 | 38.6k | return CheckARMBuiltinFunctionCall(TI, BuiltinID, TheCall); |
1955 | 412k | case llvm::Triple::aarch64: |
1956 | 413k | case llvm::Triple::aarch64_32: |
1957 | 429k | case llvm::Triple::aarch64_be: |
1958 | 429k | return CheckAArch64BuiltinFunctionCall(TI, BuiltinID, TheCall); |
1959 | 0 | case llvm::Triple::bpfeb: |
1960 | 27 | case llvm::Triple::bpfel: |
1961 | 27 | return CheckBPFBuiltinFunctionCall(BuiltinID, TheCall); |
1962 | 52 | case llvm::Triple::hexagon: |
1963 | 52 | return CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall); |
1964 | 0 | case llvm::Triple::mips: |
1965 | 0 | case llvm::Triple::mipsel: |
1966 | 0 | case llvm::Triple::mips64: |
1967 | 0 | case llvm::Triple::mips64el: |
1968 | 0 | return CheckMipsBuiltinFunctionCall(TI, BuiltinID, TheCall); |
1969 | 0 | case llvm::Triple::systemz: |
1970 | 0 | return CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall); |
1971 | 269k | case llvm::Triple::x86: |
1972 | 1.00M | case llvm::Triple::x86_64: |
1973 | 1.00M | return CheckX86BuiltinFunctionCall(TI, BuiltinID, TheCall); |
1974 | 2.13k | case llvm::Triple::ppc: |
1975 | 2.13k | case llvm::Triple::ppcle: |
1976 | 11.4k | case llvm::Triple::ppc64: |
1977 | 16.9k | case llvm::Triple::ppc64le: |
1978 | 16.9k | return CheckPPCBuiltinFunctionCall(TI, BuiltinID, TheCall); |
1979 | 712 | case llvm::Triple::amdgcn: |
1980 | 712 | return CheckAMDGCNBuiltinFunctionCall(BuiltinID, TheCall); |
1981 | 55 | case llvm::Triple::riscv32: |
1982 | 135 | case llvm::Triple::riscv64: |
1983 | 135 | return CheckRISCVBuiltinFunctionCall(TI, BuiltinID, TheCall); |
1984 | 1.49M | } |
1985 | 1.49M | } |
1986 | | |
1987 | | ExprResult |
1988 | | Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, |
1989 | 1.96M | CallExpr *TheCall) { |
1990 | 1.96M | ExprResult TheCallResult(TheCall); |
1991 | | |
1992 | | // Find out if any arguments are required to be integer constant expressions. |
1993 | 1.96M | unsigned ICEArguments = 0; |
1994 | 1.96M | ASTContext::GetBuiltinTypeError Error; |
1995 | 1.96M | Context.GetBuiltinType(BuiltinID, Error, &ICEArguments); |
1996 | 1.96M | if (Error != ASTContext::GE_None) |
1997 | 4.96k | ICEArguments = 0; // Don't diagnose previously diagnosed errors. |
1998 | | |
1999 | | // If any arguments are required to be ICE's, check and diagnose. |
2000 | 2.34M | for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo380k ) { |
2001 | | // Skip arguments not required to be ICE's. |
2002 | 380k | if ((ICEArguments & (1 << ArgNo)) == 0) continue277k ; |
2003 | | |
2004 | 102k | llvm::APSInt Result; |
2005 | | // If we don't have enough arguments, continue so we can issue better |
2006 | | // diagnostic in checkArgCount(...) |
2007 | 102k | if (ArgNo < TheCall->getNumArgs() && |
2008 | 102k | SemaBuiltinConstantArg(TheCall, ArgNo, Result)) |
2009 | 459 | return true; |
2010 | 102k | ICEArguments &= ~(1 << ArgNo); |
2011 | 102k | } |
2012 | | |
2013 | 1.96M | switch (BuiltinID) { |
2014 | 396 | case Builtin::BI__builtin___CFStringMakeConstantString: |
2015 | | // CFStringMakeConstantString is currently not implemented for GOFF (i.e., |
2016 | | // on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported |
2017 | 396 | if (CheckBuiltinTargetNotInUnsupported( |
2018 | 396 | *this, BuiltinID, TheCall, |
2019 | 396 | {llvm::Triple::GOFF, llvm::Triple::XCOFF})) |
2020 | 0 | return ExprError(); |
2021 | 396 | assert(TheCall->getNumArgs() == 1 && |
2022 | 396 | "Wrong # arguments to builtin CFStringMakeConstantString"); |
2023 | 396 | if (CheckObjCString(TheCall->getArg(0))) |
2024 | 1 | return ExprError(); |
2025 | 395 | break; |
2026 | 395 | case Builtin::BI__builtin_ms_va_start: |
2027 | 37 | case Builtin::BI__builtin_stdarg_start: |
2028 | 640 | case Builtin::BI__builtin_va_start: |
2029 | 640 | if (SemaBuiltinVAStart(BuiltinID, TheCall)) |
2030 | 33 | return ExprError(); |
2031 | 607 | break; |
2032 | 607 | case Builtin::BI__va_start: { |
2033 | 12 | switch (Context.getTargetInfo().getTriple().getArch()) { |
2034 | 2 | case llvm::Triple::aarch64: |
2035 | 2 | case llvm::Triple::arm: |
2036 | 10 | case llvm::Triple::thumb: |
2037 | 10 | if (SemaBuiltinVAStartARMMicrosoft(TheCall)) |
2038 | 3 | return ExprError(); |
2039 | 7 | break; |
2040 | 7 | default: |
2041 | 2 | if (SemaBuiltinVAStart(BuiltinID, TheCall)) |
2042 | 0 | return ExprError(); |
2043 | 2 | break; |
2044 | 12 | } |
2045 | 9 | break; |
2046 | 12 | } |
2047 | | |
2048 | | // The acquire, release, and no fence variants are ARM and AArch64 only. |
2049 | 9 | case Builtin::BI_interlockedbittestandset_acq: |
2050 | 14 | case Builtin::BI_interlockedbittestandset_rel: |
2051 | 21 | case Builtin::BI_interlockedbittestandset_nf: |
2052 | 28 | case Builtin::BI_interlockedbittestandreset_acq: |
2053 | 35 | case Builtin::BI_interlockedbittestandreset_rel: |
2054 | 42 | case Builtin::BI_interlockedbittestandreset_nf: |
2055 | 42 | if (CheckBuiltinTargetInSupported( |
2056 | 42 | *this, BuiltinID, TheCall, |
2057 | 42 | {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64})) |
2058 | 12 | return ExprError(); |
2059 | 30 | break; |
2060 | | |
2061 | | // The 64-bit bittest variants are x64, ARM, and AArch64 only. |
2062 | 30 | case Builtin::BI_bittest64: |
2063 | 16 | case Builtin::BI_bittestandcomplement64: |
2064 | 24 | case Builtin::BI_bittestandreset64: |
2065 | 32 | case Builtin::BI_bittestandset64: |
2066 | 40 | case Builtin::BI_interlockedbittestandreset64: |
2067 | 48 | case Builtin::BI_interlockedbittestandset64: |
2068 | 48 | if (CheckBuiltinTargetInSupported(*this, BuiltinID, TheCall, |
2069 | 48 | {llvm::Triple::x86_64, llvm::Triple::arm, |
2070 | 48 | llvm::Triple::thumb, |
2071 | 48 | llvm::Triple::aarch64})) |
2072 | 6 | return ExprError(); |
2073 | 42 | break; |
2074 | | |
2075 | 61 | case Builtin::BI__builtin_isgreater: |
2076 | 117 | case Builtin::BI__builtin_isgreaterequal: |
2077 | 179 | case Builtin::BI__builtin_isless: |
2078 | 238 | case Builtin::BI__builtin_islessequal: |
2079 | 294 | case Builtin::BI__builtin_islessgreater: |
2080 | 375 | case Builtin::BI__builtin_isunordered: |
2081 | 375 | if (SemaBuiltinUnorderedCompare(TheCall)) |
2082 | 4 | return ExprError(); |
2083 | 371 | break; |
2084 | 371 | case Builtin::BI__builtin_fpclassify: |
2085 | 46 | if (SemaBuiltinFPClassification(TheCall, 6)) |
2086 | 5 | return ExprError(); |
2087 | 41 | break; |
2088 | 58 | case Builtin::BI__builtin_isfinite: |
2089 | 1.53k | case Builtin::BI__builtin_isinf: |
2090 | 1.58k | case Builtin::BI__builtin_isinf_sign: |
2091 | 3.07k | case Builtin::BI__builtin_isnan: |
2092 | 3.12k | case Builtin::BI__builtin_isnormal: |
2093 | 3.14k | case Builtin::BI__builtin_signbit: |
2094 | 3.15k | case Builtin::BI__builtin_signbitf: |
2095 | 3.16k | case Builtin::BI__builtin_signbitl: |
2096 | 3.16k | if (SemaBuiltinFPClassification(TheCall, 1)) |
2097 | 7 | return ExprError(); |
2098 | 3.16k | break; |
2099 | 157k | case Builtin::BI__builtin_shufflevector: |
2100 | 157k | return SemaBuiltinShuffleVector(TheCall); |
2101 | | // TheCall will be freed by the smart pointer here, but that's fine, since |
2102 | | // SemaBuiltinShuffleVector guts it, but then doesn't release it. |
2103 | 287 | case Builtin::BI__builtin_prefetch: |
2104 | 287 | if (SemaBuiltinPrefetch(TheCall)) |
2105 | 6 | return ExprError(); |
2106 | 281 | break; |
2107 | 281 | case Builtin::BI__builtin_alloca_with_align: |
2108 | 17 | case Builtin::BI__builtin_alloca_with_align_uninitialized: |
2109 | 17 | if (SemaBuiltinAllocaWithAlign(TheCall)) |
2110 | 3 | return ExprError(); |
2111 | 17 | LLVM_FALLTHROUGH14 ;14 |
2112 | 69 | case Builtin::BI__builtin_alloca: |
2113 | 74 | case Builtin::BI__builtin_alloca_uninitialized: |
2114 | 74 | Diag(TheCall->getBeginLoc(), diag::warn_alloca) |
2115 | 74 | << TheCall->getDirectCallee(); |
2116 | 74 | break; |
2117 | 40 | case Builtin::BI__arithmetic_fence: |
2118 | 40 | if (SemaBuiltinArithmeticFence(TheCall)) |
2119 | 9 | return ExprError(); |
2120 | 31 | break; |
2121 | 31 | case Builtin::BI__assume: |
2122 | 44.2k | case Builtin::BI__builtin_assume: |
2123 | 44.2k | if (SemaBuiltinAssume(TheCall)) |
2124 | 0 | return ExprError(); |
2125 | 44.2k | break; |
2126 | 44.2k | case Builtin::BI__builtin_assume_aligned: |
2127 | 67 | if (SemaBuiltinAssumeAligned(TheCall)) |
2128 | 10 | return ExprError(); |
2129 | 57 | break; |
2130 | 295 | case Builtin::BI__builtin_dynamic_object_size: |
2131 | 854 | case Builtin::BI__builtin_object_size: |
2132 | 854 | if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3)) |
2133 | 9 | return ExprError(); |
2134 | 845 | break; |
2135 | 845 | case Builtin::BI__builtin_longjmp: |
2136 | 12 | if (SemaBuiltinLongjmp(TheCall)) |
2137 | 4 | return ExprError(); |
2138 | 8 | break; |
2139 | 10 | case Builtin::BI__builtin_setjmp: |
2140 | 10 | if (SemaBuiltinSetjmp(TheCall)) |
2141 | 4 | return ExprError(); |
2142 | 6 | break; |
2143 | 88 | case Builtin::BI__builtin_classify_type: |
2144 | 88 | if (checkArgCount(*this, TheCall, 1)) return true0 ; |
2145 | 88 | TheCall->setType(Context.IntTy); |
2146 | 88 | break; |
2147 | 44 | case Builtin::BI__builtin_complex: |
2148 | 44 | if (SemaBuiltinComplex(TheCall)) |
2149 | 24 | return ExprError(); |
2150 | 20 | break; |
2151 | 3.98k | case Builtin::BI__builtin_constant_p: { |
2152 | 3.98k | if (checkArgCount(*this, TheCall, 1)) return true2 ; |
2153 | 3.98k | ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0)); |
2154 | 3.98k | if (Arg.isInvalid()) return true0 ; |
2155 | 3.98k | TheCall->setArg(0, Arg.get()); |
2156 | 3.98k | TheCall->setType(Context.IntTy); |
2157 | 3.98k | break; |
2158 | 3.98k | } |
2159 | 120 | case Builtin::BI__builtin_launder: |
2160 | 120 | return SemaBuiltinLaunder(*this, TheCall); |
2161 | 35 | case Builtin::BI__sync_fetch_and_add: |
2162 | 35 | case Builtin::BI__sync_fetch_and_add_1: |
2163 | 35 | case Builtin::BI__sync_fetch_and_add_2: |
2164 | 40 | case Builtin::BI__sync_fetch_and_add_4: |
2165 | 40 | case Builtin::BI__sync_fetch_and_add_8: |
2166 | 40 | case Builtin::BI__sync_fetch_and_add_16: |
2167 | 59 | case Builtin::BI__sync_fetch_and_sub: |
2168 | 59 | case Builtin::BI__sync_fetch_and_sub_1: |
2169 | 59 | case Builtin::BI__sync_fetch_and_sub_2: |
2170 | 59 | case Builtin::BI__sync_fetch_and_sub_4: |
2171 | 59 | case Builtin::BI__sync_fetch_and_sub_8: |
2172 | 59 | case Builtin::BI__sync_fetch_and_sub_16: |
2173 | 77 | case Builtin::BI__sync_fetch_and_or: |
2174 | 77 | case Builtin::BI__sync_fetch_and_or_1: |
2175 | 77 | case Builtin::BI__sync_fetch_and_or_2: |
2176 | 77 | case Builtin::BI__sync_fetch_and_or_4: |
2177 | 77 | case Builtin::BI__sync_fetch_and_or_8: |
2178 | 77 | case Builtin::BI__sync_fetch_and_or_16: |
2179 | 95 | case Builtin::BI__sync_fetch_and_and: |
2180 | 95 | case Builtin::BI__sync_fetch_and_and_1: |
2181 | 95 | case Builtin::BI__sync_fetch_and_and_2: |
2182 | 95 | case Builtin::BI__sync_fetch_and_and_4: |
2183 | 95 | case Builtin::BI__sync_fetch_and_and_8: |
2184 | 95 | case Builtin::BI__sync_fetch_and_and_16: |
2185 | 115 | case Builtin::BI__sync_fetch_and_xor: |
2186 | 115 | case Builtin::BI__sync_fetch_and_xor_1: |
2187 | 115 | case Builtin::BI__sync_fetch_and_xor_2: |
2188 | 115 | case Builtin::BI__sync_fetch_and_xor_4: |
2189 | 115 | case Builtin::BI__sync_fetch_and_xor_8: |
2190 | 115 | case Builtin::BI__sync_fetch_and_xor_16: |
2191 | 134 | case Builtin::BI__sync_fetch_and_nand: |
2192 | 134 | case Builtin::BI__sync_fetch_and_nand_1: |
2193 | 134 | case Builtin::BI__sync_fetch_and_nand_2: |
2194 | 134 | case Builtin::BI__sync_fetch_and_nand_4: |
2195 | 134 | case Builtin::BI__sync_fetch_and_nand_8: |
2196 | 134 | case Builtin::BI__sync_fetch_and_nand_16: |
2197 | 146 | case Builtin::BI__sync_add_and_fetch: |
2198 | 146 | case Builtin::BI__sync_add_and_fetch_1: |
2199 | 146 | case Builtin::BI__sync_add_and_fetch_2: |
2200 | 146 | case Builtin::BI__sync_add_and_fetch_4: |
2201 | 146 | case Builtin::BI__sync_add_and_fetch_8: |
2202 | 146 | case Builtin::BI__sync_add_and_fetch_16: |
2203 | 156 | case Builtin::BI__sync_sub_and_fetch: |
2204 | 156 | case Builtin::BI__sync_sub_and_fetch_1: |
2205 | 156 | case Builtin::BI__sync_sub_and_fetch_2: |
2206 | 156 | case Builtin::BI__sync_sub_and_fetch_4: |
2207 | 156 | case Builtin::BI__sync_sub_and_fetch_8: |
2208 | 156 | case Builtin::BI__sync_sub_and_fetch_16: |
2209 | 166 | case Builtin::BI__sync_and_and_fetch: |
2210 | 166 | case Builtin::BI__sync_and_and_fetch_1: |
2211 | 166 | case Builtin::BI__sync_and_and_fetch_2: |
2212 | 166 | case Builtin::BI__sync_and_and_fetch_4: |
2213 | 166 | case Builtin::BI__sync_and_and_fetch_8: |
2214 | 166 | case Builtin::BI__sync_and_and_fetch_16: |
2215 | 176 | case Builtin::BI__sync_or_and_fetch: |
2216 | 176 | case Builtin::BI__sync_or_and_fetch_1: |
2217 | 176 | case Builtin::BI__sync_or_and_fetch_2: |
2218 | 176 | case Builtin::BI__sync_or_and_fetch_4: |
2219 | 176 | case Builtin::BI__sync_or_and_fetch_8: |
2220 | 176 | case Builtin::BI__sync_or_and_fetch_16: |
2221 | 187 | case Builtin::BI__sync_xor_and_fetch: |
2222 | 187 | case Builtin::BI__sync_xor_and_fetch_1: |
2223 | 187 | case Builtin::BI__sync_xor_and_fetch_2: |
2224 | 187 | case Builtin::BI__sync_xor_and_fetch_4: |
2225 | 187 | case Builtin::BI__sync_xor_and_fetch_8: |
2226 | 187 | case Builtin::BI__sync_xor_and_fetch_16: |
2227 | 205 | case Builtin::BI__sync_nand_and_fetch: |
2228 | 205 | case Builtin::BI__sync_nand_and_fetch_1: |
2229 | 205 | case Builtin::BI__sync_nand_and_fetch_2: |
2230 | 205 | case Builtin::BI__sync_nand_and_fetch_4: |
2231 | 205 | case Builtin::BI__sync_nand_and_fetch_8: |
2232 | 205 | case Builtin::BI__sync_nand_and_fetch_16: |
2233 | 220 | case Builtin::BI__sync_val_compare_and_swap: |
2234 | 220 | case Builtin::BI__sync_val_compare_and_swap_1: |
2235 | 220 | case Builtin::BI__sync_val_compare_and_swap_2: |
2236 | 220 | case Builtin::BI__sync_val_compare_and_swap_4: |
2237 | 220 | case Builtin::BI__sync_val_compare_and_swap_8: |
2238 | 220 | case Builtin::BI__sync_val_compare_and_swap_16: |
2239 | 235 | case Builtin::BI__sync_bool_compare_and_swap: |
2240 | 235 | case Builtin::BI__sync_bool_compare_and_swap_1: |
2241 | 235 | case Builtin::BI__sync_bool_compare_and_swap_2: |
2242 | 236 | case Builtin::BI__sync_bool_compare_and_swap_4: |
2243 | 236 | case Builtin::BI__sync_bool_compare_and_swap_8: |
2244 | 236 | case Builtin::BI__sync_bool_compare_and_swap_16: |
2245 | 249 | case Builtin::BI__sync_lock_test_and_set: |
2246 | 249 | case Builtin::BI__sync_lock_test_and_set_1: |
2247 | 249 | case Builtin::BI__sync_lock_test_and_set_2: |
2248 | 249 | case Builtin::BI__sync_lock_test_and_set_4: |
2249 | 249 | case Builtin::BI__sync_lock_test_and_set_8: |
2250 | 249 | case Builtin::BI__sync_lock_test_and_set_16: |
2251 | 261 | case Builtin::BI__sync_lock_release: |
2252 | 261 | case Builtin::BI__sync_lock_release_1: |
2253 | 261 | case Builtin::BI__sync_lock_release_2: |
2254 | 261 | case Builtin::BI__sync_lock_release_4: |
2255 | 261 | case Builtin::BI__sync_lock_release_8: |
2256 | 261 | case Builtin::BI__sync_lock_release_16: |
2257 | 266 | case Builtin::BI__sync_swap: |
2258 | 266 | case Builtin::BI__sync_swap_1: |
2259 | 266 | case Builtin::BI__sync_swap_2: |
2260 | 266 | case Builtin::BI__sync_swap_4: |
2261 | 266 | case Builtin::BI__sync_swap_8: |
2262 | 266 | case Builtin::BI__sync_swap_16: |
2263 | 266 | return SemaBuiltinAtomicOverloaded(TheCallResult); |
2264 | 3 | case Builtin::BI__sync_synchronize: |
2265 | 3 | Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst) |
2266 | 3 | << TheCall->getCallee()->getSourceRange(); |
2267 | 3 | break; |
2268 | 901 | case Builtin::BI__builtin_nontemporal_load: |
2269 | 4.31k | case Builtin::BI__builtin_nontemporal_store: |
2270 | 4.31k | return SemaBuiltinNontemporalOverloaded(TheCallResult); |
2271 | 13 | case Builtin::BI__builtin_memcpy_inline: { |
2272 | 13 | clang::Expr *SizeOp = TheCall->getArg(2); |
2273 | | // We warn about copying to or from `nullptr` pointers when `size` is |
2274 | | // greater than 0. When `size` is value dependent we cannot evaluate its |
2275 | | // value so we bail out. |
2276 | 13 | if (SizeOp->isValueDependent()) |
2277 | 1 | break; |
2278 | 12 | if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) { |
2279 | 8 | CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); |
2280 | 8 | CheckNonNullArgument(*this, TheCall->getArg(1), TheCall->getExprLoc()); |
2281 | 8 | } |
2282 | 12 | break; |
2283 | 13 | } |
2284 | 7 | case Builtin::BI__builtin_memset_inline: { |
2285 | 7 | clang::Expr *SizeOp = TheCall->getArg(2); |
2286 | | // We warn about filling to `nullptr` pointers when `size` is greater than |
2287 | | // 0. When `size` is value dependent we cannot evaluate its value so we bail |
2288 | | // out. |
2289 | 7 | if (SizeOp->isValueDependent()) |
2290 | 1 | break; |
2291 | 6 | if (!SizeOp->EvaluateKnownConstInt(Context).isZero()) |
2292 | 4 | CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); |
2293 | 6 | break; |
2294 | 7 | } |
2295 | 0 | #define BUILTIN(ID, TYPE, ATTRS) |
2296 | 0 | #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ |
2297 | 8.00k | case Builtin::BI##ID: \ |
2298 | 8.00k | return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID); |
2299 | 6 | #include "clang/Basic/Builtins.def" |
2300 | 31 | case Builtin::BI__annotation: |
2301 | 31 | if (SemaBuiltinMSVCAnnotation(*this, TheCall)) |
2302 | 9 | return ExprError(); |
2303 | 22 | break; |
2304 | 22 | case Builtin::BI__builtin_annotation: |
2305 | 12 | if (SemaBuiltinAnnotation(*this, TheCall)) |
2306 | 3 | return ExprError(); |
2307 | 9 | break; |
2308 | 188 | case Builtin::BI__builtin_addressof: |
2309 | 188 | if (SemaBuiltinAddressof(*this, TheCall)) |
2310 | 2 | return ExprError(); |
2311 | 186 | break; |
2312 | 186 | case Builtin::BI__builtin_function_start: |
2313 | 14 | if (SemaBuiltinFunctionStart(*this, TheCall)) |
2314 | 2 | return ExprError(); |
2315 | 12 | break; |
2316 | 91 | case Builtin::BI__builtin_is_aligned: |
2317 | 195 | case Builtin::BI__builtin_align_up: |
2318 | 281 | case Builtin::BI__builtin_align_down: |
2319 | 281 | if (SemaBuiltinAlignment(*this, TheCall, BuiltinID)) |
2320 | 72 | return ExprError(); |
2321 | 209 | break; |
2322 | 209 | case Builtin::BI__builtin_add_overflow: |
2323 | 53 | case Builtin::BI__builtin_sub_overflow: |
2324 | 112 | case Builtin::BI__builtin_mul_overflow: |
2325 | 112 | if (SemaBuiltinOverflow(*this, TheCall, BuiltinID)) |
2326 | 7 | return ExprError(); |
2327 | 105 | break; |
2328 | 561 | case Builtin::BI__builtin_operator_new: |
2329 | 1.10k | case Builtin::BI__builtin_operator_delete: { |
2330 | 1.10k | bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete; |
2331 | 1.10k | ExprResult Res = |
2332 | 1.10k | SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete); |
2333 | 1.10k | if (Res.isInvalid()) |
2334 | 56 | CorrectDelayedTyposInExpr(TheCallResult.get()); |
2335 | 1.10k | return Res; |
2336 | 561 | } |
2337 | 26 | case Builtin::BI__builtin_dump_struct: |
2338 | 26 | return SemaBuiltinDumpStruct(*this, TheCall); |
2339 | 38 | case Builtin::BI__builtin_expect_with_probability: { |
2340 | | // We first want to ensure we are called with 3 arguments |
2341 | 38 | if (checkArgCount(*this, TheCall, 3)) |
2342 | 0 | return ExprError(); |
2343 | | // then check probability is constant float in range [0.0, 1.0] |
2344 | 38 | const Expr *ProbArg = TheCall->getArg(2); |
2345 | 38 | SmallVector<PartialDiagnosticAt, 8> Notes; |
2346 | 38 | Expr::EvalResult Eval; |
2347 | 38 | Eval.Diag = &Notes; |
2348 | 38 | if ((!ProbArg->EvaluateAsConstantExpr(Eval, Context)) || |
2349 | 38 | !Eval.Val.isFloat()36 ) { |
2350 | 2 | Diag(ProbArg->getBeginLoc(), diag::err_probability_not_constant_float) |
2351 | 2 | << ProbArg->getSourceRange(); |
2352 | 2 | for (const PartialDiagnosticAt &PDiag : Notes) |
2353 | 4 | Diag(PDiag.first, PDiag.second); |
2354 | 2 | return ExprError(); |
2355 | 2 | } |
2356 | 36 | llvm::APFloat Probability = Eval.Val.getFloat(); |
2357 | 36 | bool LoseInfo = false; |
2358 | 36 | Probability.convert(llvm::APFloat::IEEEdouble(), |
2359 | 36 | llvm::RoundingMode::Dynamic, &LoseInfo); |
2360 | 36 | if (!(Probability >= llvm::APFloat(0.0) && |
2361 | 36 | Probability <= llvm::APFloat(1.0)30 )) { |
2362 | 12 | Diag(ProbArg->getBeginLoc(), diag::err_probability_out_of_range) |
2363 | 12 | << ProbArg->getSourceRange(); |
2364 | 12 | return ExprError(); |
2365 | 12 | } |
2366 | 24 | break; |
2367 | 36 | } |
2368 | 29 | case Builtin::BI__builtin_preserve_access_index: |
2369 | 29 | if (SemaBuiltinPreserveAI(*this, TheCall)) |
2370 | 1 | return ExprError(); |
2371 | 28 | break; |
2372 | 28 | case Builtin::BI__builtin_call_with_static_chain: |
2373 | 16 | if (SemaBuiltinCallWithStaticChain(*this, TheCall)) |
2374 | 6 | return ExprError(); |
2375 | 10 | break; |
2376 | 10 | case Builtin::BI__exception_code: |
2377 | 30 | case Builtin::BI_exception_code: |
2378 | 30 | if (SemaBuiltinSEHScopeCheck(*this, TheCall, Scope::SEHExceptScope, |
2379 | 30 | diag::err_seh___except_block)) |
2380 | 6 | return ExprError(); |
2381 | 24 | break; |
2382 | 24 | case Builtin::BI__exception_info: |
2383 | 9 | case Builtin::BI_exception_info: |
2384 | 9 | if (SemaBuiltinSEHScopeCheck(*this, TheCall, Scope::SEHFilterScope, |
2385 | 9 | diag::err_seh___except_filter)) |
2386 | 7 | return ExprError(); |
2387 | 2 | break; |
2388 | 3 | case Builtin::BI__GetExceptionInfo: |
2389 | 3 | if (checkArgCount(*this, TheCall, 1)) |
2390 | 0 | return ExprError(); |
2391 | | |
2392 | 3 | if (CheckCXXThrowOperand( |
2393 | 3 | TheCall->getBeginLoc(), |
2394 | 3 | Context.getExceptionObjectType(FDecl->getParamDecl(0)->getType()), |
2395 | 3 | TheCall)) |
2396 | 0 | return ExprError(); |
2397 | | |
2398 | 3 | TheCall->setType(Context.VoidPtrTy); |
2399 | 3 | break; |
2400 | 2.02k | case Builtin::BIaddressof: |
2401 | 2.03k | case Builtin::BI__addressof: |
2402 | 25.4k | case Builtin::BIforward: |
2403 | 42.3k | case Builtin::BImove: |
2404 | 42.4k | case Builtin::BImove_if_noexcept: |
2405 | 42.4k | case Builtin::BIas_const: { |
2406 | | // These are all expected to be of the form |
2407 | | // T &/&&/* f(U &/&&) |
2408 | | // where T and U only differ in qualification. |
2409 | 42.4k | if (checkArgCount(*this, TheCall, 1)) |
2410 | 0 | return ExprError(); |
2411 | 42.4k | QualType Param = FDecl->getParamDecl(0)->getType(); |
2412 | 42.4k | QualType Result = FDecl->getReturnType(); |
2413 | 42.4k | bool ReturnsPointer = BuiltinID == Builtin::BIaddressof || |
2414 | 42.4k | BuiltinID == Builtin::BI__addressof40.4k ; |
2415 | 42.4k | if (!(Param->isReferenceType() && |
2416 | 42.4k | (42.4k ReturnsPointer42.4k ? Result->isAnyPointerType()2.03k |
2417 | 42.4k | : Result->isReferenceType()40.4k ) && |
2418 | 42.4k | Context.hasSameUnqualifiedType(Param->getPointeeType(), |
2419 | 42.4k | Result->getPointeeType()))) { |
2420 | 3 | Diag(TheCall->getBeginLoc(), diag::err_builtin_move_forward_unsupported) |
2421 | 3 | << FDecl; |
2422 | 3 | return ExprError(); |
2423 | 3 | } |
2424 | 42.4k | break; |
2425 | 42.4k | } |
2426 | | // OpenCL v2.0, s6.13.16 - Pipe functions |
2427 | 42.4k | case Builtin::BIread_pipe: |
2428 | 36 | case Builtin::BIwrite_pipe: |
2429 | | // Since those two functions are declared with var args, we need a semantic |
2430 | | // check for the argument. |
2431 | 36 | if (SemaBuiltinRWPipe(*this, TheCall)) |
2432 | 14 | return ExprError(); |
2433 | 22 | break; |
2434 | 22 | case Builtin::BIreserve_read_pipe: |
2435 | 8 | case Builtin::BIreserve_write_pipe: |
2436 | 10 | case Builtin::BIwork_group_reserve_read_pipe: |
2437 | 12 | case Builtin::BIwork_group_reserve_write_pipe: |
2438 | 12 | if (SemaBuiltinReserveRWPipe(*this, TheCall)) |
2439 | 4 | return ExprError(); |
2440 | 8 | break; |
2441 | 8 | case Builtin::BIsub_group_reserve_read_pipe: |
2442 | 4 | case Builtin::BIsub_group_reserve_write_pipe: |
2443 | 4 | if (checkOpenCLSubgroupExt(*this, TheCall) || |
2444 | 4 | SemaBuiltinReserveRWPipe(*this, TheCall)) |
2445 | 2 | return ExprError(); |
2446 | 2 | break; |
2447 | 3 | case Builtin::BIcommit_read_pipe: |
2448 | 6 | case Builtin::BIcommit_write_pipe: |
2449 | 8 | case Builtin::BIwork_group_commit_read_pipe: |
2450 | 10 | case Builtin::BIwork_group_commit_write_pipe: |
2451 | 10 | if (SemaBuiltinCommitRWPipe(*this, TheCall)) |
2452 | 4 | return ExprError(); |
2453 | 6 | break; |
2454 | 6 | case Builtin::BIsub_group_commit_read_pipe: |
2455 | 4 | case Builtin::BIsub_group_commit_write_pipe: |
2456 | 4 | if (checkOpenCLSubgroupExt(*this, TheCall) || |
2457 | 4 | SemaBuiltinCommitRWPipe(*this, TheCall)) |
2458 | 2 | return ExprError(); |
2459 | 2 | break; |
2460 | 5 | case Builtin::BIget_pipe_num_packets: |
2461 | 10 | case Builtin::BIget_pipe_max_packets: |
2462 | 10 | if (SemaBuiltinPipePackets(*this, TheCall)) |
2463 | 2 | return ExprError(); |
2464 | 8 | break; |
2465 | 37 | case Builtin::BIto_global: |
2466 | 56 | case Builtin::BIto_local: |
2467 | 75 | case Builtin::BIto_private: |
2468 | 75 | if (SemaOpenCLBuiltinToAddr(*this, BuiltinID, TheCall)) |
2469 | 8 | return ExprError(); |
2470 | 67 | break; |
2471 | | // OpenCL v2.0, s6.13.17 - Enqueue kernel functions. |
2472 | 361 | case Builtin::BIenqueue_kernel: |
2473 | 361 | if (SemaOpenCLBuiltinEnqueueKernel(*this, TheCall)) |
2474 | 170 | return ExprError(); |
2475 | 191 | break; |
2476 | 191 | case Builtin::BIget_kernel_work_group_size: |
2477 | 232 | case Builtin::BIget_kernel_preferred_work_group_size_multiple: |
2478 | 232 | if (SemaOpenCLBuiltinKernelWorkGroupSize(*this, TheCall)) |
2479 | 140 | return ExprError(); |
2480 | 92 | break; |
2481 | 92 | case Builtin::BIget_kernel_max_sub_group_size_for_ndrange: |
2482 | 64 | case Builtin::BIget_kernel_sub_group_count_for_ndrange: |
2483 | 64 | if (SemaOpenCLBuiltinNDRangeAndBlock(*this, TheCall)) |
2484 | 36 | return ExprError(); |
2485 | 28 | break; |
2486 | 1.21k | case Builtin::BI__builtin_os_log_format: |
2487 | 1.21k | Cleanup.setExprNeedsCleanups(true); |
2488 | 1.21k | LLVM_FALLTHROUGH; |
2489 | 2.35k | case Builtin::BI__builtin_os_log_format_buffer_size: |
2490 | 2.35k | if (SemaBuiltinOSLogFormat(TheCall)) |
2491 | 2 | return ExprError(); |
2492 | 2.35k | break; |
2493 | 2.35k | case Builtin::BI__builtin_frame_address: |
2494 | 32 | case Builtin::BI__builtin_return_address: { |
2495 | 32 | if (SemaBuiltinConstantArgRange(TheCall, 0, 0, 0xFFFF)) |
2496 | 4 | return ExprError(); |
2497 | | |
2498 | | // -Wframe-address warning if non-zero passed to builtin |
2499 | | // return/frame address. |
2500 | 28 | Expr::EvalResult Result; |
2501 | 28 | if (!TheCall->getArg(0)->isValueDependent() && |
2502 | 28 | TheCall->getArg(0)->EvaluateAsInt(Result, getASTContext())27 && |
2503 | 28 | Result.Val.getInt() != 027 ) |
2504 | 8 | Diag(TheCall->getBeginLoc(), diag::warn_frame_address) |
2505 | 8 | << ((BuiltinID == Builtin::BI__builtin_return_address) |
2506 | 8 | ? "__builtin_return_address"5 |
2507 | 8 | : "__builtin_frame_address"3 ) |
2508 | 8 | << TheCall->getSourceRange(); |
2509 | 28 | break; |
2510 | 32 | } |
2511 | | |
2512 | | // __builtin_elementwise_abs restricts the element type to signed integers or |
2513 | | // floating point types only. |
2514 | 3.57k | case Builtin::BI__builtin_elementwise_abs: { |
2515 | 3.57k | if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) |
2516 | 2 | return ExprError(); |
2517 | | |
2518 | 3.57k | QualType ArgTy = TheCall->getArg(0)->getType(); |
2519 | 3.57k | QualType EltTy = ArgTy; |
2520 | | |
2521 | 3.57k | if (auto *VecTy = EltTy->getAs<VectorType>()) |
2522 | 3.56k | EltTy = VecTy->getElementType(); |
2523 | 3.57k | if (EltTy->isUnsignedIntegerType()) { |
2524 | 2 | Diag(TheCall->getArg(0)->getBeginLoc(), |
2525 | 2 | diag::err_builtin_invalid_arg_type) |
2526 | 2 | << 1 << /* signed integer or float ty*/ 3 << ArgTy; |
2527 | 2 | return ExprError(); |
2528 | 2 | } |
2529 | 3.57k | break; |
2530 | 3.57k | } |
2531 | | |
2532 | | // These builtins restrict the element type to floating point |
2533 | | // types only. |
2534 | 3.57k | case Builtin::BI__builtin_elementwise_ceil: |
2535 | 20 | case Builtin::BI__builtin_elementwise_floor: |
2536 | 29 | case Builtin::BI__builtin_elementwise_roundeven: |
2537 | 38 | case Builtin::BI__builtin_elementwise_trunc: { |
2538 | 38 | if (PrepareBuiltinElementwiseMathOneArgCall(TheCall)) |
2539 | 8 | return ExprError(); |
2540 | | |
2541 | 30 | QualType ArgTy = TheCall->getArg(0)->getType(); |
2542 | 30 | QualType EltTy = ArgTy; |
2543 | | |
2544 | 30 | if (auto *VecTy = EltTy->getAs<VectorType>()) |
2545 | 8 | EltTy = VecTy->getElementType(); |
2546 | 30 | if (!EltTy->isFloatingType()) { |
2547 | 12 | Diag(TheCall->getArg(0)->getBeginLoc(), |
2548 | 12 | diag::err_builtin_invalid_arg_type) |
2549 | 12 | << 1 << /* float ty*/ 5 << ArgTy; |
2550 | | |
2551 | 12 | return ExprError(); |
2552 | 12 | } |
2553 | 18 | break; |
2554 | 30 | } |
2555 | | |
2556 | | // These builtins restrict the element type to integer |
2557 | | // types only. |
2558 | 4.56k | case Builtin::BI__builtin_elementwise_add_sat: |
2559 | 9.12k | case Builtin::BI__builtin_elementwise_sub_sat: { |
2560 | 9.12k | if (SemaBuiltinElementwiseMath(TheCall)) |
2561 | 16 | return ExprError(); |
2562 | | |
2563 | 9.10k | const Expr *Arg = TheCall->getArg(0); |
2564 | 9.10k | QualType ArgTy = Arg->getType(); |
2565 | 9.10k | QualType EltTy = ArgTy; |
2566 | | |
2567 | 9.10k | if (auto *VecTy = EltTy->getAs<VectorType>()) |
2568 | 9.06k | EltTy = VecTy->getElementType(); |
2569 | | |
2570 | 9.10k | if (!EltTy->isIntegerType()) { |
2571 | 2 | Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type) |
2572 | 2 | << 1 << /* integer ty */ 6 << ArgTy; |
2573 | 2 | return ExprError(); |
2574 | 2 | } |
2575 | 9.10k | break; |
2576 | 9.10k | } |
2577 | | |
2578 | 9.10k | case Builtin::BI__builtin_elementwise_min: |
2579 | 15.2k | case Builtin::BI__builtin_elementwise_max: |
2580 | 15.2k | if (SemaBuiltinElementwiseMath(TheCall)) |
2581 | 16 | return ExprError(); |
2582 | 15.2k | break; |
2583 | 15.2k | case Builtin::BI__builtin_reduce_max: |
2584 | 4.73k | case Builtin::BI__builtin_reduce_min: { |
2585 | 4.73k | if (PrepareBuiltinReduceMathOneArgCall(TheCall)) |
2586 | 4 | return ExprError(); |
2587 | | |
2588 | 4.73k | const Expr *Arg = TheCall->getArg(0); |
2589 | 4.73k | const auto *TyA = Arg->getType()->getAs<VectorType>(); |
2590 | 4.73k | if (!TyA) { |
2591 | 2 | Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type) |
2592 | 2 | << 1 << /* vector ty*/ 4 << Arg->getType(); |
2593 | 2 | return ExprError(); |
2594 | 2 | } |
2595 | | |
2596 | 4.73k | TheCall->setType(TyA->getElementType()); |
2597 | 4.73k | break; |
2598 | 4.73k | } |
2599 | | |
2600 | | // These builtins support vectors of integers only. |
2601 | | // TODO: ADD/MUL should support floating-point types. |
2602 | 1.18k | case Builtin::BI__builtin_reduce_add: |
2603 | 2.37k | case Builtin::BI__builtin_reduce_mul: |
2604 | 2.38k | case Builtin::BI__builtin_reduce_xor: |
2605 | 3.57k | case Builtin::BI__builtin_reduce_or: |
2606 | 4.75k | case Builtin::BI__builtin_reduce_and: { |
2607 | 4.75k | if (PrepareBuiltinReduceMathOneArgCall(TheCall)) |
2608 | 10 | return ExprError(); |
2609 | | |
2610 | 4.74k | const Expr *Arg = TheCall->getArg(0); |
2611 | 4.74k | const auto *TyA = Arg->getType()->getAs<VectorType>(); |
2612 | 4.74k | if (!TyA || !TyA->getElementType()->isIntegerType()4.74k ) { |
2613 | 10 | Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type) |
2614 | 10 | << 1 << /* vector of integers */ 6 << Arg->getType(); |
2615 | 10 | return ExprError(); |
2616 | 10 | } |
2617 | 4.73k | TheCall->setType(TyA->getElementType()); |
2618 | 4.73k | break; |
2619 | 4.74k | } |
2620 | | |
2621 | 48 | case Builtin::BI__builtin_matrix_transpose: |
2622 | 48 | return SemaBuiltinMatrixTranspose(TheCall, TheCallResult); |
2623 | | |
2624 | 63 | case Builtin::BI__builtin_matrix_column_major_load: |
2625 | 63 | return SemaBuiltinMatrixColumnMajorLoad(TheCall, TheCallResult); |
2626 | | |
2627 | 50 | case Builtin::BI__builtin_matrix_column_major_store: |
2628 | 50 | return SemaBuiltinMatrixColumnMajorStore(TheCall, TheCallResult); |
2629 | | |
2630 | 10 | case Builtin::BI__builtin_get_device_side_mangled_name: { |
2631 | 10 | auto Check = [](CallExpr *TheCall) { |
2632 | 10 | if (TheCall->getNumArgs() != 1) |
2633 | 2 | return false; |
2634 | 8 | auto *DRE = dyn_cast<DeclRefExpr>(TheCall->getArg(0)->IgnoreImpCasts()); |
2635 | 8 | if (!DRE) |
2636 | 1 | return false; |
2637 | 7 | auto *D = DRE->getDecl(); |
2638 | 7 | if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)4 ) |
2639 | 0 | return false; |
2640 | 7 | return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>()5 || |
2641 | 7 | D->hasAttr<CUDAConstantAttr>()3 || D->hasAttr<HIPManagedAttr>()3 ; |
2642 | 7 | }; |
2643 | 10 | if (!Check(TheCall)) { |
2644 | 6 | Diag(TheCall->getBeginLoc(), |
2645 | 6 | diag::err_hip_invalid_args_builtin_mangled_name); |
2646 | 6 | return ExprError(); |
2647 | 6 | } |
2648 | 10 | } |
2649 | 1.96M | } |
2650 | | |
2651 | | // Since the target specific builtins for each arch overlap, only check those |
2652 | | // of the arch we are compiling for. |
2653 | 1.79M | if (Context.BuiltinInfo.isTSBuiltin(BuiltinID)) { |
2654 | 1.49M | if (Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) { |
2655 | 2 | assert(Context.getAuxTargetInfo() && |
2656 | 2 | "Aux Target Builtin, but not an aux target?"); |
2657 | | |
2658 | 2 | if (CheckTSBuiltinFunctionCall( |
2659 | 2 | *Context.getAuxTargetInfo(), |
2660 | 2 | Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall)) |
2661 | 1 | return ExprError(); |
2662 | 1.49M | } else { |
2663 | 1.49M | if (CheckTSBuiltinFunctionCall(Context.getTargetInfo(), BuiltinID, |
2664 | 1.49M | TheCall)) |
2665 | 1.77k | return ExprError(); |
2666 | 1.49M | } |
2667 | 1.49M | } |
2668 | | |
2669 | 1.79M | return TheCallResult; |
2670 | 1.79M | } |
2671 | | |
2672 | | // Get the valid immediate range for the specified NEON type code. |
2673 | 3.03k | static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { |
2674 | 3.03k | NeonTypeFlags Type(t); |
2675 | 3.03k | int IsQuad = ForceQuad ? true359 : Type.isQuad()2.67k ; |
2676 | 3.03k | switch (Type.getEltType()) { |
2677 | 255 | case NeonTypeFlags::Int8: |
2678 | 303 | case NeonTypeFlags::Poly8: |
2679 | 303 | return shift ? 7119 : (8 << IsQuad) - 1184 ; |
2680 | 711 | case NeonTypeFlags::Int16: |
2681 | 757 | case NeonTypeFlags::Poly16: |
2682 | 757 | return shift ? 15406 : (4 << IsQuad) - 1351 ; |
2683 | 1.10k | case NeonTypeFlags::Int32: |
2684 | 1.10k | return shift ? 31439 : (2 << IsQuad) - 1670 ; |
2685 | 489 | case NeonTypeFlags::Int64: |
2686 | 513 | case NeonTypeFlags::Poly64: |
2687 | 513 | return shift ? 63372 : (1 << IsQuad) - 1141 ; |
2688 | 0 | case NeonTypeFlags::Poly128: |
2689 | 0 | return shift ? 127 : (1 << IsQuad) - 1; |
2690 | 90 | case NeonTypeFlags::Float16: |
2691 | 90 | assert(!shift && "cannot shift float types!"); |
2692 | 0 | return (4 << IsQuad) - 1; |
2693 | 106 | case NeonTypeFlags::Float32: |
2694 | 106 | assert(!shift && "cannot shift float types!"); |
2695 | 0 | return (2 << IsQuad) - 1; |
2696 | 81 | case NeonTypeFlags::Float64: |
2697 | 81 | assert(!shift && "cannot shift float types!"); |
2698 | 0 | return (1 << IsQuad) - 1; |
2699 | 76 | case NeonTypeFlags::BFloat16: |
2700 | 76 | assert(!shift && "cannot shift float types!"); |
2701 | 0 | return (4 << IsQuad) - 1; |
2702 | 3.03k | } |
2703 | 0 | llvm_unreachable("Invalid NeonTypeFlag!"); |
2704 | 0 | } |
2705 | | |
2706 | | /// getNeonEltType - Return the QualType corresponding to the elements of |
2707 | | /// the vector type specified by the NeonTypeFlags. This is used to check |
2708 | | /// the pointer arguments for Neon load/store intrinsics. |
2709 | | static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, |
2710 | 1.46k | bool IsPolyUnsigned, bool IsInt64Long) { |
2711 | 1.46k | switch (Flags.getEltType()) { |
2712 | 222 | case NeonTypeFlags::Int8: |
2713 | 222 | return Flags.isUnsigned() ? Context.UnsignedCharTy87 : Context.SignedCharTy135 ; |
2714 | 235 | case NeonTypeFlags::Int16: |
2715 | 235 | return Flags.isUnsigned() ? Context.UnsignedShortTy93 : Context.ShortTy142 ; |
2716 | 235 | case NeonTypeFlags::Int32: |
2717 | 235 | return Flags.isUnsigned() ? Context.UnsignedIntTy93 : Context.IntTy142 ; |
2718 | 196 | case NeonTypeFlags::Int64: |
2719 | 196 | if (IsInt64Long) |
2720 | 142 | return Flags.isUnsigned() ? Context.UnsignedLongTy47 : Context.LongTy95 ; |
2721 | 54 | else |
2722 | 54 | return Flags.isUnsigned() ? Context.UnsignedLongLongTy29 |
2723 | 54 | : Context.LongLongTy25 ; |
2724 | 87 | case NeonTypeFlags::Poly8: |
2725 | 87 | return IsPolyUnsigned ? Context.UnsignedCharTy47 : Context.SignedCharTy40 ; |
2726 | 93 | case NeonTypeFlags::Poly16: |
2727 | 93 | return IsPolyUnsigned ? Context.UnsignedShortTy47 : Context.ShortTy46 ; |
2728 | 48 | case NeonTypeFlags::Poly64: |
2729 | 48 | if (IsInt64Long) |
2730 | 48 | return Context.UnsignedLongTy; |
2731 | 0 | else |
2732 | 0 | return Context.UnsignedLongLongTy; |
2733 | 0 | case NeonTypeFlags::Poly128: |
2734 | 0 | break; |
2735 | 93 | case NeonTypeFlags::Float16: |
2736 | 93 | return Context.HalfTy; |
2737 | 95 | case NeonTypeFlags::Float32: |
2738 | 95 | return Context.FloatTy; |
2739 | 47 | case NeonTypeFlags::Float64: |
2740 | 47 | return Context.DoubleTy; |
2741 | 116 | case NeonTypeFlags::BFloat16: |
2742 | 116 | return Context.BFloat16Ty; |
2743 | 1.46k | } |
2744 | 0 | llvm_unreachable("Invalid NeonTypeFlag!"); |
2745 | 0 | } |
2746 | | |
2747 | 428k | bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { |
2748 | | // Range check SVE intrinsics that take immediate values. |
2749 | 428k | SmallVector<std::tuple<int,int,int>, 3> ImmChecks; |
2750 | | |
2751 | 428k | switch (BuiltinID) { |
2752 | 423k | default: |
2753 | 423k | return false; |
2754 | 0 | #define GET_SVE_IMMEDIATE_CHECK |
2755 | 428k | #include "clang/Basic/arm_sve_sema_rangechecks.inc"423k |
2756 | 428k | #undef GET_SVE_IMMEDIATE_CHECK |
2757 | 428k | } |
2758 | | |
2759 | | // Perform all the immediate checks for this builtin call. |
2760 | 5.10k | bool HasError = false; |
2761 | 5.53k | for (auto &I : ImmChecks) { |
2762 | 5.53k | int ArgNum, CheckTy, ElementSizeInBits; |
2763 | 5.53k | std::tie(ArgNum, CheckTy, ElementSizeInBits) = I; |
2764 | | |
2765 | 5.53k | typedef bool(*OptionSetCheckFnTy)(int64_t Value); |
2766 | | |
2767 | | // Function that checks whether the operand (ArgNum) is an immediate |
2768 | | // that is one of the predefined values. |
2769 | 5.53k | auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm, |
2770 | 5.53k | int ErrDiag) -> bool { |
2771 | | // We can't check the value of a dependent argument. |
2772 | 640 | Expr *Arg = TheCall->getArg(ArgNum); |
2773 | 640 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
2774 | 0 | return false; |
2775 | | |
2776 | | // Check constant-ness first. |
2777 | 640 | llvm::APSInt Imm; |
2778 | 640 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Imm)) |
2779 | 0 | return true; |
2780 | | |
2781 | 640 | if (!CheckImm(Imm.getSExtValue())) |
2782 | 108 | return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange(); |
2783 | 532 | return false; |
2784 | 640 | }; |
2785 | | |
2786 | 5.53k | switch ((SVETypeFlags::ImmCheckType)CheckTy) { |
2787 | 572 | case SVETypeFlags::ImmCheck0_31: |
2788 | 572 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 31)) |
2789 | 0 | HasError = true; |
2790 | 572 | break; |
2791 | 441 | case SVETypeFlags::ImmCheck0_13: |
2792 | 441 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 13)) |
2793 | 16 | HasError = true; |
2794 | 441 | break; |
2795 | 656 | case SVETypeFlags::ImmCheck1_16: |
2796 | 656 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, 16)) |
2797 | 176 | HasError = true; |
2798 | 656 | break; |
2799 | 42 | case SVETypeFlags::ImmCheck0_7: |
2800 | 42 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 7)) |
2801 | 6 | HasError = true; |
2802 | 42 | break; |
2803 | 102 | case SVETypeFlags::ImmCheckExtract: |
2804 | 102 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, |
2805 | 102 | (2048 / ElementSizeInBits) - 1)) |
2806 | 22 | HasError = true; |
2807 | 102 | break; |
2808 | 669 | case SVETypeFlags::ImmCheckShiftRight: |
2809 | 669 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, ElementSizeInBits)) |
2810 | 136 | HasError = true; |
2811 | 669 | break; |
2812 | 600 | case SVETypeFlags::ImmCheckShiftRightNarrow: |
2813 | 600 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, |
2814 | 600 | ElementSizeInBits / 2)) |
2815 | 120 | HasError = true; |
2816 | 600 | break; |
2817 | 320 | case SVETypeFlags::ImmCheckShiftLeft: |
2818 | 320 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, |
2819 | 320 | ElementSizeInBits - 1)) |
2820 | 64 | HasError = true; |
2821 | 320 | break; |
2822 | 798 | case SVETypeFlags::ImmCheckLaneIndex: |
2823 | 798 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, |
2824 | 798 | (128 / (1 * ElementSizeInBits)) - 1)) |
2825 | 152 | HasError = true; |
2826 | 798 | break; |
2827 | 102 | case SVETypeFlags::ImmCheckLaneIndexCompRotate: |
2828 | 102 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, |
2829 | 102 | (128 / (2 * ElementSizeInBits)) - 1)) |
2830 | 18 | HasError = true; |
2831 | 102 | break; |
2832 | 90 | case SVETypeFlags::ImmCheckLaneIndexDot: |
2833 | 90 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, |
2834 | 90 | (128 / (4 * ElementSizeInBits)) - 1)) |
2835 | 12 | HasError = true; |
2836 | 90 | break; |
2837 | 188 | case SVETypeFlags::ImmCheckComplexRot90_270: |
2838 | 188 | if (CheckImmediateInSet([](int64_t V) { return V == 90 || V == 27095 ; }, |
2839 | 188 | diag::err_rotation_argument_to_cadd)) |
2840 | 42 | HasError = true; |
2841 | 188 | break; |
2842 | 452 | case SVETypeFlags::ImmCheckComplexRotAll90: |
2843 | 452 | if (CheckImmediateInSet( |
2844 | 452 | [](int64_t V) { |
2845 | 452 | return V == 0 || V == 90338 || V == 180246 || V == 270154 ; |
2846 | 452 | }, |
2847 | 452 | diag::err_rotation_argument_to_cmla)) |
2848 | 66 | HasError = true; |
2849 | 452 | break; |
2850 | 159 | case SVETypeFlags::ImmCheck0_1: |
2851 | 159 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 1)) |
2852 | 44 | HasError = true; |
2853 | 159 | break; |
2854 | 167 | case SVETypeFlags::ImmCheck0_2: |
2855 | 167 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 2)) |
2856 | 44 | HasError = true; |
2857 | 167 | break; |
2858 | 181 | case SVETypeFlags::ImmCheck0_3: |
2859 | 181 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 3)) |
2860 | 42 | HasError = true; |
2861 | 181 | break; |
2862 | 5.53k | } |
2863 | 5.53k | } |
2864 | | |
2865 | 5.10k | return HasError; |
2866 | 5.10k | } |
2867 | | |
2868 | | bool Sema::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, |
2869 | 467k | unsigned BuiltinID, CallExpr *TheCall) { |
2870 | 467k | llvm::APSInt Result; |
2871 | 467k | uint64_t mask = 0; |
2872 | 467k | unsigned TV = 0; |
2873 | 467k | int PtrArgNum = -1; |
2874 | 467k | bool HasConstPtr = false; |
2875 | 467k | switch (BuiltinID) { |
2876 | 0 | #define GET_NEON_OVERLOAD_CHECK |
2877 | 467k | #include "clang/Basic/arm_neon.inc"0 |
2878 | 467k | #include "clang/Basic/arm_fp16.inc" |
2879 | 467k | #undef GET_NEON_OVERLOAD_CHECK |
2880 | 467k | } |
2881 | | |
2882 | | // For NEON intrinsics which are overloaded on vector element type, validate |
2883 | | // the immediate which specifies which variant to emit. |
2884 | 467k | unsigned ImmArg = TheCall->getNumArgs()-1; |
2885 | 467k | if (mask) { |
2886 | 145k | if (SemaBuiltinConstantArg(TheCall, ImmArg, Result)) |
2887 | 0 | return true; |
2888 | | |
2889 | 145k | TV = Result.getLimitedValue(64); |
2890 | 145k | if ((TV > 63) || (mask & (1ULL << TV)) == 0) |
2891 | 0 | return Diag(TheCall->getBeginLoc(), diag::err_invalid_neon_type_code) |
2892 | 0 | << TheCall->getArg(ImmArg)->getSourceRange(); |
2893 | 145k | } |
2894 | | |
2895 | 467k | if (PtrArgNum >= 0) { |
2896 | | // Check that pointer arguments have the specified type. |
2897 | 1.46k | Expr *Arg = TheCall->getArg(PtrArgNum); |
2898 | 1.46k | if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) |
2899 | 1.46k | Arg = ICE->getSubExpr(); |
2900 | 1.46k | ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); |
2901 | 1.46k | QualType RHSTy = RHS.get()->getType(); |
2902 | | |
2903 | 1.46k | llvm::Triple::ArchType Arch = TI.getTriple().getArch(); |
2904 | 1.46k | bool IsPolyUnsigned = Arch == llvm::Triple::aarch64 || |
2905 | 1.46k | Arch == llvm::Triple::aarch64_32546 || |
2906 | 1.46k | Arch == llvm::Triple::aarch64_be546 ; |
2907 | 1.46k | bool IsInt64Long = TI.getInt64Type() == TargetInfo::SignedLong; |
2908 | 1.46k | QualType EltTy = |
2909 | 1.46k | getNeonEltType(NeonTypeFlags(TV), Context, IsPolyUnsigned, IsInt64Long); |
2910 | 1.46k | if (HasConstPtr) |
2911 | 824 | EltTy = EltTy.withConst(); |
2912 | 1.46k | QualType LHSTy = Context.getPointerType(EltTy); |
2913 | 1.46k | AssignConvertType ConvTy; |
2914 | 1.46k | ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS); |
2915 | 1.46k | if (RHS.isInvalid()) |
2916 | 0 | return true; |
2917 | 1.46k | if (DiagnoseAssignmentResult(ConvTy, Arg->getBeginLoc(), LHSTy, RHSTy, |
2918 | 1.46k | RHS.get(), AA_Assigning)) |
2919 | 0 | return true; |
2920 | 1.46k | } |
2921 | | |
2922 | | // For NEON intrinsics which take an immediate value as part of the |
2923 | | // instruction, range check them here. |
2924 | 467k | unsigned i = 0, l = 0, u = 0; |
2925 | 467k | switch (BuiltinID) { |
2926 | 463k | default: |
2927 | 463k | return false; |
2928 | 0 | #define GET_NEON_IMMEDIATE_CHECK |
2929 | 463k | #include "clang/Basic/arm_neon.inc" |
2930 | 467k | #include "clang/Basic/arm_fp16.inc"5 |
2931 | 467k | #undef GET_NEON_IMMEDIATE_CHECK |
2932 | 467k | } |
2933 | | |
2934 | 3.86k | return SemaBuiltinConstantArgRange(TheCall, i, l, u + l); |
2935 | 467k | } |
2936 | | |
2937 | 38.4k | bool Sema::CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { |
2938 | 38.4k | switch (BuiltinID) { |
2939 | 37.3k | default: |
2940 | 37.3k | return false; |
2941 | 38.4k | #include "clang/Basic/arm_mve_builtin_sema.inc"2 |
2942 | 38.4k | } |
2943 | 38.4k | } |
2944 | | |
2945 | | bool Sema::CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
2946 | 38.3k | CallExpr *TheCall) { |
2947 | 38.3k | bool Err = false; |
2948 | 38.3k | switch (BuiltinID) { |
2949 | 38.2k | default: |
2950 | 38.2k | return false; |
2951 | 38.3k | #include "clang/Basic/arm_cde_builtin_sema.inc"9 |
2952 | 38.3k | } |
2953 | | |
2954 | 120 | if (Err) |
2955 | 67 | return true; |
2956 | | |
2957 | 53 | return CheckARMCoprocessorImmediate(TI, TheCall->getArg(0), /*WantCDE*/ true); |
2958 | 120 | } |
2959 | | |
2960 | | bool Sema::CheckARMCoprocessorImmediate(const TargetInfo &TI, |
2961 | 113 | const Expr *CoprocArg, bool WantCDE) { |
2962 | 113 | if (isConstantEvaluated()) |
2963 | 0 | return false; |
2964 | | |
2965 | | // We can't check the value of a dependent argument. |
2966 | 113 | if (CoprocArg->isTypeDependent() || CoprocArg->isValueDependent()) |
2967 | 0 | return false; |
2968 | | |
2969 | 113 | llvm::APSInt CoprocNoAP = *CoprocArg->getIntegerConstantExpr(Context); |
2970 | 113 | int64_t CoprocNo = CoprocNoAP.getExtValue(); |
2971 | 113 | assert(CoprocNo >= 0 && "Coprocessor immediate must be non-negative"); |
2972 | | |
2973 | 0 | uint32_t CDECoprocMask = TI.getARMCDECoprocMask(); |
2974 | 113 | bool IsCDECoproc = CoprocNo <= 7 && (CDECoprocMask & (1 << CoprocNo))97 ; |
2975 | | |
2976 | 113 | if (IsCDECoproc != WantCDE) |
2977 | 19 | return Diag(CoprocArg->getBeginLoc(), diag::err_arm_invalid_coproc) |
2978 | 19 | << (int)CoprocNo << (int)WantCDE << CoprocArg->getSourceRange(); |
2979 | | |
2980 | 94 | return false; |
2981 | 113 | } |
2982 | | |
2983 | | bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, |
2984 | 259 | unsigned MaxWidth) { |
2985 | 259 | assert((BuiltinID == ARM::BI__builtin_arm_ldrex || |
2986 | 259 | BuiltinID == ARM::BI__builtin_arm_ldaex || |
2987 | 259 | BuiltinID == ARM::BI__builtin_arm_strex || |
2988 | 259 | BuiltinID == ARM::BI__builtin_arm_stlex || |
2989 | 259 | BuiltinID == AArch64::BI__builtin_arm_ldrex || |
2990 | 259 | BuiltinID == AArch64::BI__builtin_arm_ldaex || |
2991 | 259 | BuiltinID == AArch64::BI__builtin_arm_strex || |
2992 | 259 | BuiltinID == AArch64::BI__builtin_arm_stlex) && |
2993 | 259 | "unexpected ARM builtin"); |
2994 | 259 | bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex || |
2995 | 259 | BuiltinID == ARM::BI__builtin_arm_ldaex224 || |
2996 | 259 | BuiltinID == AArch64::BI__builtin_arm_ldrex201 || |
2997 | 259 | BuiltinID == AArch64::BI__builtin_arm_ldaex154 ; |
2998 | | |
2999 | 259 | DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); |
3000 | | |
3001 | | // Ensure that we have the proper number of arguments. |
3002 | 259 | if (checkArgCount(*this, TheCall, IsLdrex ? 1129 : 2130 )) |
3003 | 16 | return true; |
3004 | | |
3005 | | // Inspect the pointer argument of the atomic builtin. This should always be |
3006 | | // a pointer type, whose element is an integral scalar or pointer type. |
3007 | | // Because it is a pointer type, we don't have to worry about any implicit |
3008 | | // casts here. |
3009 | 243 | Expr *PointerArg = TheCall->getArg(IsLdrex ? 0121 : 1122 ); |
3010 | 243 | ExprResult PointerArgRes = DefaultFunctionArrayLvalueConversion(PointerArg); |
3011 | 243 | if (PointerArgRes.isInvalid()) |
3012 | 0 | return true; |
3013 | 243 | PointerArg = PointerArgRes.get(); |
3014 | | |
3015 | 243 | const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>(); |
3016 | 243 | if (!pointerType) { |
3017 | 0 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) |
3018 | 0 | << PointerArg->getType() << PointerArg->getSourceRange(); |
3019 | 0 | return true; |
3020 | 0 | } |
3021 | | |
3022 | | // ldrex takes a "const volatile T*" and strex takes a "volatile T*". Our next |
3023 | | // task is to insert the appropriate casts into the AST. First work out just |
3024 | | // what the appropriate type is. |
3025 | 243 | QualType ValType = pointerType->getPointeeType(); |
3026 | 243 | QualType AddrType = ValType.getUnqualifiedType().withVolatile(); |
3027 | 243 | if (IsLdrex) |
3028 | 121 | AddrType.addConst(); |
3029 | | |
3030 | | // Issue a warning if the cast is dodgy. |
3031 | 243 | CastKind CastNeeded = CK_NoOp; |
3032 | 243 | if (!AddrType.isAtLeastAsQualifiedAs(ValType)) { |
3033 | 4 | CastNeeded = CK_BitCast; |
3034 | 4 | Diag(DRE->getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers) |
3035 | 4 | << PointerArg->getType() << Context.getPointerType(AddrType) |
3036 | 4 | << AA_Passing << PointerArg->getSourceRange(); |
3037 | 4 | } |
3038 | | |
3039 | | // Finally, do the cast and replace the argument with the corrected version. |
3040 | 243 | AddrType = Context.getPointerType(AddrType); |
3041 | 243 | PointerArgRes = ImpCastExprToType(PointerArg, AddrType, CastNeeded); |
3042 | 243 | if (PointerArgRes.isInvalid()) |
3043 | 0 | return true; |
3044 | 243 | PointerArg = PointerArgRes.get(); |
3045 | | |
3046 | 243 | TheCall->setArg(IsLdrex ? 0121 : 1122 , PointerArg); |
3047 | | |
3048 | | // In general, we allow ints, floats and pointers to be loaded and stored. |
3049 | 243 | if (!ValType->isIntegerType() && !ValType->isAnyPointerType()72 && |
3050 | 243 | !ValType->isBlockPointerType()40 && !ValType->isFloatingType()40 ) { |
3051 | 8 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr) |
3052 | 8 | << PointerArg->getType() << PointerArg->getSourceRange(); |
3053 | 8 | return true; |
3054 | 8 | } |
3055 | | |
3056 | | // But ARM doesn't have instructions to deal with 128-bit versions. |
3057 | 235 | if (Context.getTypeSize(ValType) > MaxWidth) { |
3058 | 4 | assert(MaxWidth == 64 && "Diagnostic unexpectedly inaccurate"); |
3059 | 0 | Diag(DRE->getBeginLoc(), diag::err_atomic_exclusive_builtin_pointer_size) |
3060 | 4 | << PointerArg->getType() << PointerArg->getSourceRange(); |
3061 | 4 | return true; |
3062 | 4 | } |
3063 | | |
3064 | 231 | switch (ValType.getObjCLifetime()) { |
3065 | 231 | case Qualifiers::OCL_None: |
3066 | 231 | case Qualifiers::OCL_ExplicitNone: |
3067 | | // okay |
3068 | 231 | break; |
3069 | | |
3070 | 0 | case Qualifiers::OCL_Weak: |
3071 | 0 | case Qualifiers::OCL_Strong: |
3072 | 0 | case Qualifiers::OCL_Autoreleasing: |
3073 | 0 | Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership) |
3074 | 0 | << ValType << PointerArg->getSourceRange(); |
3075 | 0 | return true; |
3076 | 231 | } |
3077 | | |
3078 | 231 | if (IsLdrex) { |
3079 | 115 | TheCall->setType(ValType); |
3080 | 115 | return false; |
3081 | 115 | } |
3082 | | |
3083 | | // Initialize the argument to be stored. |
3084 | 116 | ExprResult ValArg = TheCall->getArg(0); |
3085 | 116 | InitializedEntity Entity = InitializedEntity::InitializeParameter( |
3086 | 116 | Context, ValType, /*consume*/ false); |
3087 | 116 | ValArg = PerformCopyInitialization(Entity, SourceLocation(), ValArg); |
3088 | 116 | if (ValArg.isInvalid()) |
3089 | 4 | return true; |
3090 | 112 | TheCall->setArg(0, ValArg.get()); |
3091 | | |
3092 | | // __builtin_arm_strex always returns an int. It's marked as such in the .def, |
3093 | | // but the custom checker bypasses all default analysis. |
3094 | 112 | TheCall->setType(Context.IntTy); |
3095 | 112 | return false; |
3096 | 116 | } |
3097 | | |
3098 | | bool Sema::CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
3099 | 38.6k | CallExpr *TheCall) { |
3100 | 38.6k | if (BuiltinID == ARM::BI__builtin_arm_ldrex || |
3101 | 38.6k | BuiltinID == ARM::BI__builtin_arm_ldaex38.6k || |
3102 | 38.6k | BuiltinID == ARM::BI__builtin_arm_strex38.6k || |
3103 | 38.6k | BuiltinID == ARM::BI__builtin_arm_stlex38.5k ) { |
3104 | 117 | return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64); |
3105 | 117 | } |
3106 | | |
3107 | 38.5k | if (BuiltinID == ARM::BI__builtin_arm_prefetch) { |
3108 | 12 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || |
3109 | 12 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 1)9 ; |
3110 | 12 | } |
3111 | | |
3112 | 38.5k | if (BuiltinID == ARM::BI__builtin_arm_rsr64 || |
3113 | 38.5k | BuiltinID == ARM::BI__builtin_arm_wsr6438.5k ) |
3114 | 15 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 3, false); |
3115 | | |
3116 | 38.5k | if (BuiltinID == ARM::BI__builtin_arm_rsr || |
3117 | 38.5k | BuiltinID == ARM::BI__builtin_arm_rsrp38.5k || |
3118 | 38.5k | BuiltinID == ARM::BI__builtin_arm_wsr38.5k || |
3119 | 38.5k | BuiltinID == ARM::BI__builtin_arm_wsrp38.5k ) |
3120 | 28 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); |
3121 | | |
3122 | 38.4k | if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall)) |
3123 | 46 | return true; |
3124 | 38.4k | if (CheckMVEBuiltinFunctionCall(BuiltinID, TheCall)) |
3125 | 94 | return true; |
3126 | 38.3k | if (CheckCDEBuiltinFunctionCall(TI, BuiltinID, TheCall)) |
3127 | 68 | return true; |
3128 | | |
3129 | | // For intrinsics which take an immediate value as part of the instruction, |
3130 | | // range check them here. |
3131 | | // FIXME: VFP Intrinsics should error if VFP not present. |
3132 | 38.2k | switch (BuiltinID) { |
3133 | 38.1k | default: return false; |
3134 | 14 | case ARM::BI__builtin_arm_ssat: |
3135 | 14 | return SemaBuiltinConstantArgRange(TheCall, 1, 1, 32); |
3136 | 12 | case ARM::BI__builtin_arm_usat: |
3137 | 12 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 31); |
3138 | 9 | case ARM::BI__builtin_arm_ssat16: |
3139 | 9 | return SemaBuiltinConstantArgRange(TheCall, 1, 1, 16); |
3140 | 7 | case ARM::BI__builtin_arm_usat16: |
3141 | 7 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15); |
3142 | 18 | case ARM::BI__builtin_arm_vcvtr_f: |
3143 | 20 | case ARM::BI__builtin_arm_vcvtr_d: |
3144 | 20 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1); |
3145 | 9 | case ARM::BI__builtin_arm_dmb: |
3146 | 14 | case ARM::BI__builtin_arm_dsb: |
3147 | 19 | case ARM::BI__builtin_arm_isb: |
3148 | 24 | case ARM::BI__builtin_arm_dbg: |
3149 | 24 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 15); |
3150 | 2 | case ARM::BI__builtin_arm_cdp: |
3151 | 4 | case ARM::BI__builtin_arm_cdp2: |
3152 | 6 | case ARM::BI__builtin_arm_mcr: |
3153 | 8 | case ARM::BI__builtin_arm_mcr2: |
3154 | 10 | case ARM::BI__builtin_arm_mrc: |
3155 | 12 | case ARM::BI__builtin_arm_mrc2: |
3156 | 16 | case ARM::BI__builtin_arm_mcrr: |
3157 | 20 | case ARM::BI__builtin_arm_mcrr2: |
3158 | 24 | case ARM::BI__builtin_arm_mrrc: |
3159 | 28 | case ARM::BI__builtin_arm_mrrc2: |
3160 | 32 | case ARM::BI__builtin_arm_ldc: |
3161 | 36 | case ARM::BI__builtin_arm_ldcl: |
3162 | 40 | case ARM::BI__builtin_arm_ldc2: |
3163 | 44 | case ARM::BI__builtin_arm_ldc2l: |
3164 | 48 | case ARM::BI__builtin_arm_stc: |
3165 | 52 | case ARM::BI__builtin_arm_stcl: |
3166 | 56 | case ARM::BI__builtin_arm_stc2: |
3167 | 60 | case ARM::BI__builtin_arm_stc2l: |
3168 | 60 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 15) || |
3169 | 60 | CheckARMCoprocessorImmediate(TI, TheCall->getArg(0), |
3170 | 60 | /*WantCDE*/ false); |
3171 | 38.2k | } |
3172 | 38.2k | } |
3173 | | |
3174 | | bool Sema::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, |
3175 | | unsigned BuiltinID, |
3176 | 429k | CallExpr *TheCall) { |
3177 | 429k | if (BuiltinID == AArch64::BI__builtin_arm_ldrex || |
3178 | 429k | BuiltinID == AArch64::BI__builtin_arm_ldaex429k || |
3179 | 429k | BuiltinID == AArch64::BI__builtin_arm_strex428k || |
3180 | 429k | BuiltinID == AArch64::BI__builtin_arm_stlex428k ) { |
3181 | 142 | return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128); |
3182 | 142 | } |
3183 | | |
3184 | 428k | if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { |
3185 | 32 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || |
3186 | 32 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 2)30 || |
3187 | 32 | SemaBuiltinConstantArgRange(TheCall, 3, 0, 1)28 || |
3188 | 32 | SemaBuiltinConstantArgRange(TheCall, 4, 0, 1)26 ; |
3189 | 32 | } |
3190 | | |
3191 | 428k | if (BuiltinID == AArch64::BI__builtin_arm_rsr64 || |
3192 | 428k | BuiltinID == AArch64::BI__builtin_arm_wsr64428k ) |
3193 | 33 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); |
3194 | | |
3195 | | // Memory Tagging Extensions (MTE) Intrinsics |
3196 | 428k | if (BuiltinID == AArch64::BI__builtin_arm_irg || |
3197 | 428k | BuiltinID == AArch64::BI__builtin_arm_addg428k || |
3198 | 428k | BuiltinID == AArch64::BI__builtin_arm_gmi428k || |
3199 | 428k | BuiltinID == AArch64::BI__builtin_arm_ldg428k || |
3200 | 428k | BuiltinID == AArch64::BI__builtin_arm_stg428k || |
3201 | 428k | BuiltinID == AArch64::BI__builtin_arm_subp428k ) { |
3202 | 54 | return SemaBuiltinARMMemoryTaggingCall(BuiltinID, TheCall); |
3203 | 54 | } |
3204 | | |
3205 | 428k | if (BuiltinID == AArch64::BI__builtin_arm_rsr || |
3206 | 428k | BuiltinID == AArch64::BI__builtin_arm_rsrp428k || |
3207 | 428k | BuiltinID == AArch64::BI__builtin_arm_wsr428k || |
3208 | 428k | BuiltinID == AArch64::BI__builtin_arm_wsrp428k ) |
3209 | 52 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); |
3210 | | |
3211 | | // Only check the valid encoding range. Any constant in this range would be |
3212 | | // converted to a register of the form S1_2_C3_C4_5. Let the hardware throw |
3213 | | // an exception for incorrect registers. This matches MSVC behavior. |
3214 | 428k | if (BuiltinID == AArch64::BI_ReadStatusReg || |
3215 | 428k | BuiltinID == AArch64::BI_WriteStatusReg428k ) |
3216 | 82 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 0x7fff); |
3217 | | |
3218 | 428k | if (BuiltinID == AArch64::BI__getReg) |
3219 | 4 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31); |
3220 | | |
3221 | 428k | if (BuiltinID == AArch64::BI__break) |
3222 | 4 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 0xffff); |
3223 | | |
3224 | 428k | if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall)) |
3225 | 360 | return true; |
3226 | | |
3227 | 428k | if (CheckSVEBuiltinFunctionCall(BuiltinID, TheCall)) |
3228 | 960 | return true; |
3229 | | |
3230 | | // For intrinsics which take an immediate value as part of the instruction, |
3231 | | // range check them here. |
3232 | 427k | unsigned i = 0, l = 0, u = 0; |
3233 | 427k | switch (BuiltinID) { |
3234 | 427k | default: return false; |
3235 | 10 | case AArch64::BI__builtin_arm_dmb: |
3236 | 18 | case AArch64::BI__builtin_arm_dsb: |
3237 | 26 | case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break; |
3238 | 6 | case AArch64::BI__builtin_arm_tcancel: l = 0; u = 65535; break; |
3239 | 427k | } |
3240 | | |
3241 | 32 | return SemaBuiltinConstantArgRange(TheCall, i, l, u + l); |
3242 | 427k | } |
3243 | | |
3244 | 9 | static bool isValidBPFPreserveFieldInfoArg(Expr *Arg) { |
3245 | 9 | if (Arg->getType()->getAsPlaceholderType()) |
3246 | 0 | return false; |
3247 | | |
3248 | | // The first argument needs to be a record field access. |
3249 | | // If it is an array element access, we delay decision |
3250 | | // to BPF backend to check whether the access is a |
3251 | | // field access or not. |
3252 | 9 | return (Arg->IgnoreParens()->getObjectKind() == OK_BitField || |
3253 | 9 | isa<MemberExpr>(Arg->IgnoreParens())7 || |
3254 | 9 | isa<ArraySubscriptExpr>(Arg->IgnoreParens())4 ); |
3255 | 9 | } |
3256 | | |
3257 | 7 | static bool isValidBPFPreserveTypeInfoArg(Expr *Arg) { |
3258 | 7 | QualType ArgType = Arg->getType(); |
3259 | 7 | if (ArgType->getAsPlaceholderType()) |
3260 | 0 | return false; |
3261 | | |
3262 | | // for TYPE_EXISTENCE/TYPE_MATCH/TYPE_SIZEOF reloc type |
3263 | | // format: |
3264 | | // 1. __builtin_preserve_type_info(*(<type> *)0, flag); |
3265 | | // 2. <type> var; |
3266 | | // __builtin_preserve_type_info(var, flag); |
3267 | 7 | if (!isa<DeclRefExpr>(Arg->IgnoreParens()) && |
3268 | 7 | !isa<UnaryOperator>(Arg->IgnoreParens())4 ) |
3269 | 1 | return false; |
3270 | | |
3271 | | // Typedef type. |
3272 | 6 | if (ArgType->getAs<TypedefType>()) |
3273 | 2 | return true; |
3274 | | |
3275 | | // Record type or Enum type. |
3276 | 4 | const Type *Ty = ArgType->getUnqualifiedDesugaredType(); |
3277 | 4 | if (const auto *RT = Ty->getAs<RecordType>()) { |
3278 | 2 | if (!RT->getDecl()->getDeclName().isEmpty()) |
3279 | 2 | return true; |
3280 | 2 | } else if (const auto *ET = Ty->getAs<EnumType>()) { |
3281 | 2 | if (!ET->getDecl()->getDeclName().isEmpty()) |
3282 | 2 | return true; |
3283 | 2 | } |
3284 | | |
3285 | 0 | return false; |
3286 | 4 | } |
3287 | | |
3288 | 4 | static bool isValidBPFPreserveEnumValueArg(Expr *Arg) { |
3289 | 4 | QualType ArgType = Arg->getType(); |
3290 | 4 | if (ArgType->getAsPlaceholderType()) |
3291 | 0 | return false; |
3292 | | |
3293 | | // for ENUM_VALUE_EXISTENCE/ENUM_VALUE reloc type |
3294 | | // format: |
3295 | | // __builtin_preserve_enum_value(*(<enum_type> *)<enum_value>, |
3296 | | // flag); |
3297 | 4 | const auto *UO = dyn_cast<UnaryOperator>(Arg->IgnoreParens()); |
3298 | 4 | if (!UO) |
3299 | 0 | return false; |
3300 | | |
3301 | 4 | const auto *CE = dyn_cast<CStyleCastExpr>(UO->getSubExpr()); |
3302 | 4 | if (!CE) |
3303 | 0 | return false; |
3304 | 4 | if (CE->getCastKind() != CK_IntegralToPointer && |
3305 | 4 | CE->getCastKind() != CK_NullToPointer1 ) |
3306 | 0 | return false; |
3307 | | |
3308 | | // The integer must be from an EnumConstantDecl. |
3309 | 4 | const auto *DR = dyn_cast<DeclRefExpr>(CE->getSubExpr()); |
3310 | 4 | if (!DR) |
3311 | 1 | return false; |
3312 | | |
3313 | 3 | const EnumConstantDecl *Enumerator = |
3314 | 3 | dyn_cast<EnumConstantDecl>(DR->getDecl()); |
3315 | 3 | if (!Enumerator) |
3316 | 0 | return false; |
3317 | | |
3318 | | // The type must be EnumType. |
3319 | 3 | const Type *Ty = ArgType->getUnqualifiedDesugaredType(); |
3320 | 3 | const auto *ET = Ty->getAs<EnumType>(); |
3321 | 3 | if (!ET) |
3322 | 0 | return false; |
3323 | | |
3324 | | // The enum value must be supported. |
3325 | 3 | return llvm::is_contained(ET->getDecl()->enumerators(), Enumerator); |
3326 | 3 | } |
3327 | | |
3328 | | bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID, |
3329 | 27 | CallExpr *TheCall) { |
3330 | 27 | assert((BuiltinID == BPF::BI__builtin_preserve_field_info || |
3331 | 27 | BuiltinID == BPF::BI__builtin_btf_type_id || |
3332 | 27 | BuiltinID == BPF::BI__builtin_preserve_type_info || |
3333 | 27 | BuiltinID == BPF::BI__builtin_preserve_enum_value) && |
3334 | 27 | "unexpected BPF builtin"); |
3335 | | |
3336 | 27 | if (checkArgCount(*this, TheCall, 2)) |
3337 | 1 | return true; |
3338 | | |
3339 | | // The second argument needs to be a constant int |
3340 | 26 | Expr *Arg = TheCall->getArg(1); |
3341 | 26 | Optional<llvm::APSInt> Value = Arg->getIntegerConstantExpr(Context); |
3342 | 26 | diag::kind kind; |
3343 | 26 | if (!Value) { |
3344 | 3 | if (BuiltinID == BPF::BI__builtin_preserve_field_info) |
3345 | 2 | kind = diag::err_preserve_field_info_not_const; |
3346 | 1 | else if (BuiltinID == BPF::BI__builtin_btf_type_id) |
3347 | 1 | kind = diag::err_btf_type_id_not_const; |
3348 | 0 | else if (BuiltinID == BPF::BI__builtin_preserve_type_info) |
3349 | 0 | kind = diag::err_preserve_type_info_not_const; |
3350 | 0 | else |
3351 | 0 | kind = diag::err_preserve_enum_value_not_const; |
3352 | 3 | Diag(Arg->getBeginLoc(), kind) << 2 << Arg->getSourceRange(); |
3353 | 3 | return true; |
3354 | 3 | } |
3355 | | |
3356 | | // The first argument |
3357 | 23 | Arg = TheCall->getArg(0); |
3358 | 23 | bool InvalidArg = false; |
3359 | 23 | bool ReturnUnsignedInt = true; |
3360 | 23 | if (BuiltinID == BPF::BI__builtin_preserve_field_info) { |
3361 | 9 | if (!isValidBPFPreserveFieldInfoArg(Arg)) { |
3362 | 2 | InvalidArg = true; |
3363 | 2 | kind = diag::err_preserve_field_info_not_field; |
3364 | 2 | } |
3365 | 14 | } else if (BuiltinID == BPF::BI__builtin_preserve_type_info) { |
3366 | 7 | if (!isValidBPFPreserveTypeInfoArg(Arg)) { |
3367 | 1 | InvalidArg = true; |
3368 | 1 | kind = diag::err_preserve_type_info_invalid; |
3369 | 1 | } |
3370 | 7 | } else if (BuiltinID == BPF::BI__builtin_preserve_enum_value) { |
3371 | 4 | if (!isValidBPFPreserveEnumValueArg(Arg)) { |
3372 | 2 | InvalidArg = true; |
3373 | 2 | kind = diag::err_preserve_enum_value_invalid; |
3374 | 2 | } |
3375 | 4 | ReturnUnsignedInt = false; |
3376 | 4 | } else if (3 BuiltinID == BPF::BI__builtin_btf_type_id3 ) { |
3377 | 3 | ReturnUnsignedInt = false; |
3378 | 3 | } |
3379 | | |
3380 | 23 | if (InvalidArg) { |
3381 | 5 | Diag(Arg->getBeginLoc(), kind) << 1 << Arg->getSourceRange(); |
3382 | 5 | return true; |
3383 | 5 | } |
3384 | | |
3385 | 18 | if (ReturnUnsignedInt) |
3386 | 13 | TheCall->setType(Context.UnsignedIntTy); |
3387 | 5 | else |
3388 | 5 | TheCall->setType(Context.UnsignedLongTy); |
3389 | 18 | return false; |
3390 | 23 | } |
3391 | | |
3392 | 52 | bool Sema::CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { |
3393 | 52 | struct ArgInfo { |
3394 | 52 | uint8_t OpNum; |
3395 | 52 | bool IsSigned; |
3396 | 52 | uint8_t BitWidth; |
3397 | 52 | uint8_t Align; |
3398 | 52 | }; |
3399 | 52 | struct BuiltinInfo { |
3400 | 52 | unsigned BuiltinID; |
3401 | 52 | ArgInfo Infos[2]; |
3402 | 52 | }; |
3403 | | |
3404 | 52 | static BuiltinInfo Infos[] = { |
3405 | 52 | { Hexagon::BI__builtin_circ_ldd, {{ 3, true, 4, 3 }} }, |
3406 | 52 | { Hexagon::BI__builtin_circ_ldw, {{ 3, true, 4, 2 }} }, |
3407 | 52 | { Hexagon::BI__builtin_circ_ldh, {{ 3, true, 4, 1 }} }, |
3408 | 52 | { Hexagon::BI__builtin_circ_lduh, {{ 3, true, 4, 1 }} }, |
3409 | 52 | { Hexagon::BI__builtin_circ_ldb, {{ 3, true, 4, 0 }} }, |
3410 | 52 | { Hexagon::BI__builtin_circ_ldub, {{ 3, true, 4, 0 }} }, |
3411 | 52 | { Hexagon::BI__builtin_circ_std, {{ 3, true, 4, 3 }} }, |
3412 | 52 | { Hexagon::BI__builtin_circ_stw, {{ 3, true, 4, 2 }} }, |
3413 | 52 | { Hexagon::BI__builtin_circ_sth, {{ 3, true, 4, 1 }} }, |
3414 | 52 | { Hexagon::BI__builtin_circ_sthhi, {{ 3, true, 4, 1 }} }, |
3415 | 52 | { Hexagon::BI__builtin_circ_stb, {{ 3, true, 4, 0 }} }, |
3416 | | |
3417 | 52 | { Hexagon::BI__builtin_HEXAGON_L2_loadrub_pci, {{ 1, true, 4, 0 }} }, |
3418 | 52 | { Hexagon::BI__builtin_HEXAGON_L2_loadrb_pci, {{ 1, true, 4, 0 }} }, |
3419 | 52 | { Hexagon::BI__builtin_HEXAGON_L2_loadruh_pci, {{ 1, true, 4, 1 }} }, |
3420 | 52 | { Hexagon::BI__builtin_HEXAGON_L2_loadrh_pci, {{ 1, true, 4, 1 }} }, |
3421 | 52 | { Hexagon::BI__builtin_HEXAGON_L2_loadri_pci, {{ 1, true, 4, 2 }} }, |
3422 | 52 | { Hexagon::BI__builtin_HEXAGON_L2_loadrd_pci, {{ 1, true, 4, 3 }} }, |
3423 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_storerb_pci, {{ 1, true, 4, 0 }} }, |
3424 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_storerh_pci, {{ 1, true, 4, 1 }} }, |
3425 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_storerf_pci, {{ 1, true, 4, 1 }} }, |
3426 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_storeri_pci, {{ 1, true, 4, 2 }} }, |
3427 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_storerd_pci, {{ 1, true, 4, 3 }} }, |
3428 | | |
3429 | 52 | { Hexagon::BI__builtin_HEXAGON_A2_combineii, {{ 1, true, 8, 0 }} }, |
3430 | 52 | { Hexagon::BI__builtin_HEXAGON_A2_tfrih, {{ 1, false, 16, 0 }} }, |
3431 | 52 | { Hexagon::BI__builtin_HEXAGON_A2_tfril, {{ 1, false, 16, 0 }} }, |
3432 | 52 | { Hexagon::BI__builtin_HEXAGON_A2_tfrpi, {{ 0, true, 8, 0 }} }, |
3433 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_bitspliti, {{ 1, false, 5, 0 }} }, |
3434 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_cmpbeqi, {{ 1, false, 8, 0 }} }, |
3435 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_cmpbgti, {{ 1, true, 8, 0 }} }, |
3436 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_cround_ri, {{ 1, false, 5, 0 }} }, |
3437 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_round_ri, {{ 1, false, 5, 0 }} }, |
3438 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_round_ri_sat, {{ 1, false, 5, 0 }} }, |
3439 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpbeqi, {{ 1, false, 8, 0 }} }, |
3440 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgti, {{ 1, true, 8, 0 }} }, |
3441 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgtui, {{ 1, false, 7, 0 }} }, |
3442 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpheqi, {{ 1, true, 8, 0 }} }, |
3443 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmphgti, {{ 1, true, 8, 0 }} }, |
3444 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmphgtui, {{ 1, false, 7, 0 }} }, |
3445 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpweqi, {{ 1, true, 8, 0 }} }, |
3446 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgti, {{ 1, true, 8, 0 }} }, |
3447 | 52 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgtui, {{ 1, false, 7, 0 }} }, |
3448 | 52 | { Hexagon::BI__builtin_HEXAGON_C2_bitsclri, {{ 1, false, 6, 0 }} }, |
3449 | 52 | { Hexagon::BI__builtin_HEXAGON_C2_muxii, {{ 2, true, 8, 0 }} }, |
3450 | 52 | { Hexagon::BI__builtin_HEXAGON_C4_nbitsclri, {{ 1, false, 6, 0 }} }, |
3451 | 52 | { Hexagon::BI__builtin_HEXAGON_F2_dfclass, {{ 1, false, 5, 0 }} }, |
3452 | 52 | { Hexagon::BI__builtin_HEXAGON_F2_dfimm_n, {{ 0, false, 10, 0 }} }, |
3453 | 52 | { Hexagon::BI__builtin_HEXAGON_F2_dfimm_p, {{ 0, false, 10, 0 }} }, |
3454 | 52 | { Hexagon::BI__builtin_HEXAGON_F2_sfclass, {{ 1, false, 5, 0 }} }, |
3455 | 52 | { Hexagon::BI__builtin_HEXAGON_F2_sfimm_n, {{ 0, false, 10, 0 }} }, |
3456 | 52 | { Hexagon::BI__builtin_HEXAGON_F2_sfimm_p, {{ 0, false, 10, 0 }} }, |
3457 | 52 | { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addi, {{ 2, false, 6, 0 }} }, |
3458 | 52 | { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addr_u2, {{ 1, false, 6, 2 }} }, |
3459 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_addasl_rrri, {{ 2, false, 3, 0 }} }, |
3460 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_acc, {{ 2, false, 6, 0 }} }, |
3461 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_and, {{ 2, false, 6, 0 }} }, |
3462 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p, {{ 1, false, 6, 0 }} }, |
3463 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_nac, {{ 2, false, 6, 0 }} }, |
3464 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_or, {{ 2, false, 6, 0 }} }, |
3465 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_xacc, {{ 2, false, 6, 0 }} }, |
3466 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_acc, {{ 2, false, 5, 0 }} }, |
3467 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_and, {{ 2, false, 5, 0 }} }, |
3468 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r, {{ 1, false, 5, 0 }} }, |
3469 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_nac, {{ 2, false, 5, 0 }} }, |
3470 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_or, {{ 2, false, 5, 0 }} }, |
3471 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_sat, {{ 1, false, 5, 0 }} }, |
3472 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_xacc, {{ 2, false, 5, 0 }} }, |
3473 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vh, {{ 1, false, 4, 0 }} }, |
3474 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vw, {{ 1, false, 5, 0 }} }, |
3475 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_acc, {{ 2, false, 6, 0 }} }, |
3476 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_and, {{ 2, false, 6, 0 }} }, |
3477 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p, {{ 1, false, 6, 0 }} }, |
3478 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_nac, {{ 2, false, 6, 0 }} }, |
3479 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_or, {{ 2, false, 6, 0 }} }, |
3480 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax, |
3481 | 52 | {{ 1, false, 6, 0 }} }, |
3482 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd, {{ 1, false, 6, 0 }} }, |
3483 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_acc, {{ 2, false, 5, 0 }} }, |
3484 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_and, {{ 2, false, 5, 0 }} }, |
3485 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r, {{ 1, false, 5, 0 }} }, |
3486 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_nac, {{ 2, false, 5, 0 }} }, |
3487 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_or, {{ 2, false, 5, 0 }} }, |
3488 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax, |
3489 | 52 | {{ 1, false, 5, 0 }} }, |
3490 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd, {{ 1, false, 5, 0 }} }, |
3491 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_svw_trun, {{ 1, false, 5, 0 }} }, |
3492 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vh, {{ 1, false, 4, 0 }} }, |
3493 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vw, {{ 1, false, 5, 0 }} }, |
3494 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_clrbit_i, {{ 1, false, 5, 0 }} }, |
3495 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_extractu, {{ 1, false, 5, 0 }, |
3496 | 52 | { 2, false, 5, 0 }} }, |
3497 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_extractup, {{ 1, false, 6, 0 }, |
3498 | 52 | { 2, false, 6, 0 }} }, |
3499 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_insert, {{ 2, false, 5, 0 }, |
3500 | 52 | { 3, false, 5, 0 }} }, |
3501 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_insertp, {{ 2, false, 6, 0 }, |
3502 | 52 | { 3, false, 6, 0 }} }, |
3503 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_acc, {{ 2, false, 6, 0 }} }, |
3504 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_and, {{ 2, false, 6, 0 }} }, |
3505 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p, {{ 1, false, 6, 0 }} }, |
3506 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_nac, {{ 2, false, 6, 0 }} }, |
3507 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_or, {{ 2, false, 6, 0 }} }, |
3508 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_xacc, {{ 2, false, 6, 0 }} }, |
3509 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_acc, {{ 2, false, 5, 0 }} }, |
3510 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_and, {{ 2, false, 5, 0 }} }, |
3511 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r, {{ 1, false, 5, 0 }} }, |
3512 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_nac, {{ 2, false, 5, 0 }} }, |
3513 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_or, {{ 2, false, 5, 0 }} }, |
3514 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_xacc, {{ 2, false, 5, 0 }} }, |
3515 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vh, {{ 1, false, 4, 0 }} }, |
3516 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vw, {{ 1, false, 5, 0 }} }, |
3517 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_setbit_i, {{ 1, false, 5, 0 }} }, |
3518 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxb_goodsyntax, |
3519 | 52 | {{ 2, false, 4, 0 }, |
3520 | 52 | { 3, false, 5, 0 }} }, |
3521 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxd_goodsyntax, |
3522 | 52 | {{ 2, false, 4, 0 }, |
3523 | 52 | { 3, false, 5, 0 }} }, |
3524 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxh_goodsyntax, |
3525 | 52 | {{ 2, false, 4, 0 }, |
3526 | 52 | { 3, false, 5, 0 }} }, |
3527 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxw_goodsyntax, |
3528 | 52 | {{ 2, false, 4, 0 }, |
3529 | 52 | { 3, false, 5, 0 }} }, |
3530 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_togglebit_i, {{ 1, false, 5, 0 }} }, |
3531 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_tstbit_i, {{ 1, false, 5, 0 }} }, |
3532 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_valignib, {{ 2, false, 3, 0 }} }, |
3533 | 52 | { Hexagon::BI__builtin_HEXAGON_S2_vspliceib, {{ 2, false, 3, 0 }} }, |
3534 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_addi_asl_ri, {{ 2, false, 5, 0 }} }, |
3535 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_addi_lsr_ri, {{ 2, false, 5, 0 }} }, |
3536 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_andi_asl_ri, {{ 2, false, 5, 0 }} }, |
3537 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_andi_lsr_ri, {{ 2, false, 5, 0 }} }, |
3538 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_clbaddi, {{ 1, true , 6, 0 }} }, |
3539 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_clbpaddi, {{ 1, true, 6, 0 }} }, |
3540 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_extract, {{ 1, false, 5, 0 }, |
3541 | 52 | { 2, false, 5, 0 }} }, |
3542 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_extractp, {{ 1, false, 6, 0 }, |
3543 | 52 | { 2, false, 6, 0 }} }, |
3544 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_lsli, {{ 0, true, 6, 0 }} }, |
3545 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_ntstbit_i, {{ 1, false, 5, 0 }} }, |
3546 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_ori_asl_ri, {{ 2, false, 5, 0 }} }, |
3547 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_ori_lsr_ri, {{ 2, false, 5, 0 }} }, |
3548 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_subi_asl_ri, {{ 2, false, 5, 0 }} }, |
3549 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_subi_lsr_ri, {{ 2, false, 5, 0 }} }, |
3550 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate_acc, {{ 3, false, 2, 0 }} }, |
3551 | 52 | { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate, {{ 2, false, 2, 0 }} }, |
3552 | 52 | { Hexagon::BI__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax, |
3553 | 52 | {{ 1, false, 4, 0 }} }, |
3554 | 52 | { Hexagon::BI__builtin_HEXAGON_S5_asrhub_sat, {{ 1, false, 4, 0 }} }, |
3555 | 52 | { Hexagon::BI__builtin_HEXAGON_S5_vasrhrnd_goodsyntax, |
3556 | 52 | {{ 1, false, 4, 0 }} }, |
3557 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p, {{ 1, false, 6, 0 }} }, |
3558 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_acc, {{ 2, false, 6, 0 }} }, |
3559 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_and, {{ 2, false, 6, 0 }} }, |
3560 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_nac, {{ 2, false, 6, 0 }} }, |
3561 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_or, {{ 2, false, 6, 0 }} }, |
3562 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_xacc, {{ 2, false, 6, 0 }} }, |
3563 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r, {{ 1, false, 5, 0 }} }, |
3564 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_acc, {{ 2, false, 5, 0 }} }, |
3565 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_and, {{ 2, false, 5, 0 }} }, |
3566 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_nac, {{ 2, false, 5, 0 }} }, |
3567 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_or, {{ 2, false, 5, 0 }} }, |
3568 | 52 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_xacc, {{ 2, false, 5, 0 }} }, |
3569 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_valignbi, {{ 2, false, 3, 0 }} }, |
3570 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_valignbi_128B, {{ 2, false, 3, 0 }} }, |
3571 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi, {{ 2, false, 3, 0 }} }, |
3572 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi_128B, {{ 2, false, 3, 0 }} }, |
3573 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi, {{ 2, false, 1, 0 }} }, |
3574 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_128B, {{ 2, false, 1, 0 }} }, |
3575 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc, {{ 3, false, 1, 0 }} }, |
3576 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc_128B, |
3577 | 52 | {{ 3, false, 1, 0 }} }, |
3578 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi, {{ 2, false, 1, 0 }} }, |
3579 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_128B, {{ 2, false, 1, 0 }} }, |
3580 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc, {{ 3, false, 1, 0 }} }, |
3581 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc_128B, |
3582 | 52 | {{ 3, false, 1, 0 }} }, |
3583 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi, {{ 2, false, 1, 0 }} }, |
3584 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_128B, {{ 2, false, 1, 0 }} }, |
3585 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc, {{ 3, false, 1, 0 }} }, |
3586 | 52 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc_128B, |
3587 | 52 | {{ 3, false, 1, 0 }} }, |
3588 | 52 | }; |
3589 | | |
3590 | | // Use a dynamically initialized static to sort the table exactly once on |
3591 | | // first run. |
3592 | 52 | static const bool SortOnce = |
3593 | 52 | (llvm::sort(Infos, |
3594 | 1.48k | [](const BuiltinInfo &LHS, const BuiltinInfo &RHS) { |
3595 | 1.48k | return LHS.BuiltinID < RHS.BuiltinID; |
3596 | 1.48k | }), |
3597 | 52 | true); |
3598 | 52 | (void)SortOnce; |
3599 | | |
3600 | 52 | const BuiltinInfo *F = llvm::partition_point( |
3601 | 364 | Infos, [=](const BuiltinInfo &BI) { return BI.BuiltinID < BuiltinID; }); |
3602 | 52 | if (F == std::end(Infos) || F->BuiltinID != BuiltinID) |
3603 | 52 | return false; |
3604 | | |
3605 | 0 | bool Error = false; |
3606 | |
|
3607 | 0 | for (const ArgInfo &A : F->Infos) { |
3608 | | // Ignore empty ArgInfo elements. |
3609 | 0 | if (A.BitWidth == 0) |
3610 | 0 | continue; |
3611 | | |
3612 | 0 | int32_t Min = A.IsSigned ? -(1 << (A.BitWidth - 1)) : 0; |
3613 | 0 | int32_t Max = (1 << (A.IsSigned ? A.BitWidth - 1 : A.BitWidth)) - 1; |
3614 | 0 | if (!A.Align) { |
3615 | 0 | Error |= SemaBuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); |
3616 | 0 | } else { |
3617 | 0 | unsigned M = 1 << A.Align; |
3618 | 0 | Min *= M; |
3619 | 0 | Max *= M; |
3620 | 0 | Error |= SemaBuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); |
3621 | 0 | Error |= SemaBuiltinConstantArgMultiple(TheCall, A.OpNum, M); |
3622 | 0 | } |
3623 | 0 | } |
3624 | 0 | return Error; |
3625 | 52 | } |
3626 | | |
3627 | | bool Sema::CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, |
3628 | 52 | CallExpr *TheCall) { |
3629 | 52 | return CheckHexagonBuiltinArgument(BuiltinID, TheCall); |
3630 | 52 | } |
3631 | | |
3632 | | bool Sema::CheckMipsBuiltinFunctionCall(const TargetInfo &TI, |
3633 | 0 | unsigned BuiltinID, CallExpr *TheCall) { |
3634 | 0 | return CheckMipsBuiltinCpu(TI, BuiltinID, TheCall) || |
3635 | 0 | CheckMipsBuiltinArgument(BuiltinID, TheCall); |
3636 | 0 | } |
3637 | | |
3638 | | bool Sema::CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, |
3639 | 0 | CallExpr *TheCall) { |
3640 | |
|
3641 | 0 | if (Mips::BI__builtin_mips_addu_qb <= BuiltinID && |
3642 | 0 | BuiltinID <= Mips::BI__builtin_mips_lwx) { |
3643 | 0 | if (!TI.hasFeature("dsp")) |
3644 | 0 | return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_dsp); |
3645 | 0 | } |
3646 | | |
3647 | 0 | if (Mips::BI__builtin_mips_absq_s_qb <= BuiltinID && |
3648 | 0 | BuiltinID <= Mips::BI__builtin_mips_subuh_r_qb) { |
3649 | 0 | if (!TI.hasFeature("dspr2")) |
3650 | 0 | return Diag(TheCall->getBeginLoc(), |
3651 | 0 | diag::err_mips_builtin_requires_dspr2); |
3652 | 0 | } |
3653 | | |
3654 | 0 | if (Mips::BI__builtin_msa_add_a_b <= BuiltinID && |
3655 | 0 | BuiltinID <= Mips::BI__builtin_msa_xori_b) { |
3656 | 0 | if (!TI.hasFeature("msa")) |
3657 | 0 | return Diag(TheCall->getBeginLoc(), diag::err_mips_builtin_requires_msa); |
3658 | 0 | } |
3659 | | |
3660 | 0 | return false; |
3661 | 0 | } |
3662 | | |
3663 | | // CheckMipsBuiltinArgument - Checks the constant value passed to the |
3664 | | // intrinsic is correct. The switch statement is ordered by DSP, MSA. The |
3665 | | // ordering for DSP is unspecified. MSA is ordered by the data format used |
3666 | | // by the underlying instruction i.e., df/m, df/n and then by size. |
3667 | | // |
3668 | | // FIXME: The size tests here should instead be tablegen'd along with the |
3669 | | // definitions from include/clang/Basic/BuiltinsMips.def. |
3670 | | // FIXME: GCC is strict on signedness for some of these intrinsics, we should |
3671 | | // be too. |
3672 | 0 | bool Sema::CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { |
3673 | 0 | unsigned i = 0, l = 0, u = 0, m = 0; |
3674 | 0 | switch (BuiltinID) { |
3675 | 0 | default: return false; |
3676 | 0 | case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; |
3677 | 0 | case Mips::BI__builtin_mips_rddsp: i = 0; l = 0; u = 63; break; |
3678 | 0 | case Mips::BI__builtin_mips_append: i = 2; l = 0; u = 31; break; |
3679 | 0 | case Mips::BI__builtin_mips_balign: i = 2; l = 0; u = 3; break; |
3680 | 0 | case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break; |
3681 | 0 | case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break; |
3682 | 0 | case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; |
3683 | | // MSA intrinsics. Instructions (which the intrinsics maps to) which use the |
3684 | | // df/m field. |
3685 | | // These intrinsics take an unsigned 3 bit immediate. |
3686 | 0 | case Mips::BI__builtin_msa_bclri_b: |
3687 | 0 | case Mips::BI__builtin_msa_bnegi_b: |
3688 | 0 | case Mips::BI__builtin_msa_bseti_b: |
3689 | 0 | case Mips::BI__builtin_msa_sat_s_b: |
3690 | 0 | case Mips::BI__builtin_msa_sat_u_b: |
3691 | 0 | case Mips::BI__builtin_msa_slli_b: |
3692 | 0 | case Mips::BI__builtin_msa_srai_b: |
3693 | 0 | case Mips::BI__builtin_msa_srari_b: |
3694 | 0 | case Mips::BI__builtin_msa_srli_b: |
3695 | 0 | case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break; |
3696 | 0 | case Mips::BI__builtin_msa_binsli_b: |
3697 | 0 | case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break; |
3698 | | // These intrinsics take an unsigned 4 bit immediate. |
3699 | 0 | case Mips::BI__builtin_msa_bclri_h: |
3700 | 0 | case Mips::BI__builtin_msa_bnegi_h: |
3701 | 0 | case Mips::BI__builtin_msa_bseti_h: |
3702 | 0 | case Mips::BI__builtin_msa_sat_s_h: |
3703 | 0 | case Mips::BI__builtin_msa_sat_u_h: |
3704 | 0 | case Mips::BI__builtin_msa_slli_h: |
3705 | 0 | case Mips::BI__builtin_msa_srai_h: |
3706 | 0 | case Mips::BI__builtin_msa_srari_h: |
3707 | 0 | case Mips::BI__builtin_msa_srli_h: |
3708 | 0 | case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break; |
3709 | 0 | case Mips::BI__builtin_msa_binsli_h: |
3710 | 0 | case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break; |
3711 | | // These intrinsics take an unsigned 5 bit immediate. |
3712 | | // The first block of intrinsics actually have an unsigned 5 bit field, |
3713 | | // not a df/n field. |
3714 | 0 | case Mips::BI__builtin_msa_cfcmsa: |
3715 | 0 | case Mips::BI__builtin_msa_ctcmsa: i = 0; l = 0; u = 31; break; |
3716 | 0 | case Mips::BI__builtin_msa_clei_u_b: |
3717 | 0 | case Mips::BI__builtin_msa_clei_u_h: |
3718 | 0 | case Mips::BI__builtin_msa_clei_u_w: |
3719 | 0 | case Mips::BI__builtin_msa_clei_u_d: |
3720 | 0 | case Mips::BI__builtin_msa_clti_u_b: |
3721 | 0 | case Mips::BI__builtin_msa_clti_u_h: |
3722 | 0 | case Mips::BI__builtin_msa_clti_u_w: |
3723 | 0 | case Mips::BI__builtin_msa_clti_u_d: |
3724 | 0 | case Mips::BI__builtin_msa_maxi_u_b: |
3725 | 0 | case Mips::BI__builtin_msa_maxi_u_h: |
3726 | 0 | case Mips::BI__builtin_msa_maxi_u_w: |
3727 | 0 | case Mips::BI__builtin_msa_maxi_u_d: |
3728 | 0 | case Mips::BI__builtin_msa_mini_u_b: |
3729 | 0 | case Mips::BI__builtin_msa_mini_u_h: |
3730 | 0 | case Mips::BI__builtin_msa_mini_u_w: |
3731 | 0 | case Mips::BI__builtin_msa_mini_u_d: |
3732 | 0 | case Mips::BI__builtin_msa_addvi_b: |
3733 | 0 | case Mips::BI__builtin_msa_addvi_h: |
3734 | 0 | case Mips::BI__builtin_msa_addvi_w: |
3735 | 0 | case Mips::BI__builtin_msa_addvi_d: |
3736 | 0 | case Mips::BI__builtin_msa_bclri_w: |
3737 | 0 | case Mips::BI__builtin_msa_bnegi_w: |
3738 | 0 | case Mips::BI__builtin_msa_bseti_w: |
3739 | 0 | case Mips::BI__builtin_msa_sat_s_w: |
3740 | 0 | case Mips::BI__builtin_msa_sat_u_w: |
3741 | 0 | case Mips::BI__builtin_msa_slli_w: |
3742 | 0 | case Mips::BI__builtin_msa_srai_w: |
3743 | 0 | case Mips::BI__builtin_msa_srari_w: |
3744 | 0 | case Mips::BI__builtin_msa_srli_w: |
3745 | 0 | case Mips::BI__builtin_msa_srlri_w: |
3746 | 0 | case Mips::BI__builtin_msa_subvi_b: |
3747 | 0 | case Mips::BI__builtin_msa_subvi_h: |
3748 | 0 | case Mips::BI__builtin_msa_subvi_w: |
3749 | 0 | case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break; |
3750 | 0 | case Mips::BI__builtin_msa_binsli_w: |
3751 | 0 | case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break; |
3752 | | // These intrinsics take an unsigned 6 bit immediate. |
3753 | 0 | case Mips::BI__builtin_msa_bclri_d: |
3754 | 0 | case Mips::BI__builtin_msa_bnegi_d: |
3755 | 0 | case Mips::BI__builtin_msa_bseti_d: |
3756 | 0 | case Mips::BI__builtin_msa_sat_s_d: |
3757 | 0 | case Mips::BI__builtin_msa_sat_u_d: |
3758 | 0 | case Mips::BI__builtin_msa_slli_d: |
3759 | 0 | case Mips::BI__builtin_msa_srai_d: |
3760 | 0 | case Mips::BI__builtin_msa_srari_d: |
3761 | 0 | case Mips::BI__builtin_msa_srli_d: |
3762 | 0 | case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break; |
3763 | 0 | case Mips::BI__builtin_msa_binsli_d: |
3764 | 0 | case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break; |
3765 | | // These intrinsics take a signed 5 bit immediate. |
3766 | 0 | case Mips::BI__builtin_msa_ceqi_b: |
3767 | 0 | case Mips::BI__builtin_msa_ceqi_h: |
3768 | 0 | case Mips::BI__builtin_msa_ceqi_w: |
3769 | 0 | case Mips::BI__builtin_msa_ceqi_d: |
3770 | 0 | case Mips::BI__builtin_msa_clti_s_b: |
3771 | 0 | case Mips::BI__builtin_msa_clti_s_h: |
3772 | 0 | case Mips::BI__builtin_msa_clti_s_w: |
3773 | 0 | case Mips::BI__builtin_msa_clti_s_d: |
3774 | 0 | case Mips::BI__builtin_msa_clei_s_b: |
3775 | 0 | case Mips::BI__builtin_msa_clei_s_h: |
3776 | 0 | case Mips::BI__builtin_msa_clei_s_w: |
3777 | 0 | case Mips::BI__builtin_msa_clei_s_d: |
3778 | 0 | case Mips::BI__builtin_msa_maxi_s_b: |
3779 | 0 | case Mips::BI__builtin_msa_maxi_s_h: |
3780 | 0 | case Mips::BI__builtin_msa_maxi_s_w: |
3781 | 0 | case Mips::BI__builtin_msa_maxi_s_d: |
3782 | 0 | case Mips::BI__builtin_msa_mini_s_b: |
3783 | 0 | case Mips::BI__builtin_msa_mini_s_h: |
3784 | 0 | case Mips::BI__builtin_msa_mini_s_w: |
3785 | 0 | case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break; |
3786 | | // These intrinsics take an unsigned 8 bit immediate. |
3787 | 0 | case Mips::BI__builtin_msa_andi_b: |
3788 | 0 | case Mips::BI__builtin_msa_nori_b: |
3789 | 0 | case Mips::BI__builtin_msa_ori_b: |
3790 | 0 | case Mips::BI__builtin_msa_shf_b: |
3791 | 0 | case Mips::BI__builtin_msa_shf_h: |
3792 | 0 | case Mips::BI__builtin_msa_shf_w: |
3793 | 0 | case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break; |
3794 | 0 | case Mips::BI__builtin_msa_bseli_b: |
3795 | 0 | case Mips::BI__builtin_msa_bmnzi_b: |
3796 | 0 | case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break; |
3797 | | // df/n format |
3798 | | // These intrinsics take an unsigned 4 bit immediate. |
3799 | 0 | case Mips::BI__builtin_msa_copy_s_b: |
3800 | 0 | case Mips::BI__builtin_msa_copy_u_b: |
3801 | 0 | case Mips::BI__builtin_msa_insve_b: |
3802 | 0 | case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; |
3803 | 0 | case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; |
3804 | | // These intrinsics take an unsigned 3 bit immediate. |
3805 | 0 | case Mips::BI__builtin_msa_copy_s_h: |
3806 | 0 | case Mips::BI__builtin_msa_copy_u_h: |
3807 | 0 | case Mips::BI__builtin_msa_insve_h: |
3808 | 0 | case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; |
3809 | 0 | case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; |
3810 | | // These intrinsics take an unsigned 2 bit immediate. |
3811 | 0 | case Mips::BI__builtin_msa_copy_s_w: |
3812 | 0 | case Mips::BI__builtin_msa_copy_u_w: |
3813 | 0 | case Mips::BI__builtin_msa_insve_w: |
3814 | 0 | case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; |
3815 | 0 | case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; |
3816 | | // These intrinsics take an unsigned 1 bit immediate. |
3817 | 0 | case Mips::BI__builtin_msa_copy_s_d: |
3818 | 0 | case Mips::BI__builtin_msa_copy_u_d: |
3819 | 0 | case Mips::BI__builtin_msa_insve_d: |
3820 | 0 | case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; |
3821 | 0 | case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; |
3822 | | // Memory offsets and immediate loads. |
3823 | | // These intrinsics take a signed 10 bit immediate. |
3824 | 0 | case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break; |
3825 | 0 | case Mips::BI__builtin_msa_ldi_h: |
3826 | 0 | case Mips::BI__builtin_msa_ldi_w: |
3827 | 0 | case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; |
3828 | 0 | case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 1; break; |
3829 | 0 | case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 2; break; |
3830 | 0 | case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 4; break; |
3831 | 0 | case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 8; break; |
3832 | 0 | case Mips::BI__builtin_msa_ldr_d: i = 1; l = -4096; u = 4088; m = 8; break; |
3833 | 0 | case Mips::BI__builtin_msa_ldr_w: i = 1; l = -2048; u = 2044; m = 4; break; |
3834 | 0 | case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 1; break; |
3835 | 0 | case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 2; break; |
3836 | 0 | case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 4; break; |
3837 | 0 | case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 8; break; |
3838 | 0 | case Mips::BI__builtin_msa_str_d: i = 2; l = -4096; u = 4088; m = 8; break; |
3839 | 0 | case Mips::BI__builtin_msa_str_w: i = 2; l = -2048; u = 2044; m = 4; break; |
3840 | 0 | } |
3841 | | |
3842 | 0 | if (!m) |
3843 | 0 | return SemaBuiltinConstantArgRange(TheCall, i, l, u); |
3844 | | |
3845 | 0 | return SemaBuiltinConstantArgRange(TheCall, i, l, u) || |
3846 | 0 | SemaBuiltinConstantArgMultiple(TheCall, i, m); |
3847 | 0 | } |
3848 | | |
3849 | | /// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str, |
3850 | | /// advancing the pointer over the consumed characters. The decoded type is |
3851 | | /// returned. If the decoded type represents a constant integer with a |
3852 | | /// constraint on its value then Mask is set to that value. The type descriptors |
3853 | | /// used in Str are specific to PPC MMA builtins and are documented in the file |
3854 | | /// defining the PPC builtins. |
3855 | | static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str, |
3856 | 1.10k | unsigned &Mask) { |
3857 | 1.10k | bool RequireICE = false; |
3858 | 1.10k | ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None; |
3859 | 1.10k | switch (*Str++) { |
3860 | 274 | case 'V': |
3861 | 274 | return Context.getVectorType(Context.UnsignedCharTy, 16, |
3862 | 274 | VectorType::VectorKind::AltiVecVector); |
3863 | 162 | case 'i': { |
3864 | 162 | char *End; |
3865 | 162 | unsigned size = strtoul(Str, &End, 10); |
3866 | 162 | assert(End != Str && "Missing constant parameter constraint"); |
3867 | 0 | Str = End; |
3868 | 162 | Mask = size; |
3869 | 162 | return Context.IntTy; |
3870 | 0 | } |
3871 | 362 | case 'W': { |
3872 | 362 | char *End; |
3873 | 362 | unsigned size = strtoul(Str, &End, 10); |
3874 | 362 | assert(End != Str && "Missing PowerPC MMA type size"); |
3875 | 0 | Str = End; |
3876 | 362 | QualType Type; |
3877 | 362 | switch (size) { |
3878 | 0 | #define PPC_VECTOR_TYPE(typeName, Id, size) \ |
3879 | 362 | case size: Type = Context.Id##Ty; break; |
3880 | 0 | #include "clang/Basic/PPCTypes.def" |
3881 | 0 | default: llvm_unreachable("Invalid PowerPC MMA vector type"); |
3882 | 362 | } |
3883 | 362 | bool CheckVectorArgs = false; |
3884 | 1.01k | while (!CheckVectorArgs) { |
3885 | 654 | switch (*Str++) { |
3886 | 248 | case '*': |
3887 | 248 | Type = Context.getPointerType(Type); |
3888 | 248 | break; |
3889 | 44 | case 'C': |
3890 | 44 | Type = Type.withConst(); |
3891 | 44 | break; |
3892 | 362 | default: |
3893 | 362 | CheckVectorArgs = true; |
3894 | 362 | --Str; |
3895 | 362 | break; |
3896 | 654 | } |
3897 | 654 | } |
3898 | 362 | return Type; |
3899 | 362 | } |
3900 | 302 | default: |
3901 | 302 | return Context.DecodeTypeStr(--Str, Context, Error, RequireICE, true); |
3902 | 1.10k | } |
3903 | 1.10k | } |
3904 | | |
3905 | 16.9k | static bool isPPC_64Builtin(unsigned BuiltinID) { |
3906 | | // These builtins only work on PPC 64bit targets. |
3907 | 16.9k | switch (BuiltinID) { |
3908 | 0 | case PPC::BI__builtin_divde: |
3909 | 0 | case PPC::BI__builtin_divdeu: |
3910 | 0 | case PPC::BI__builtin_bpermd: |
3911 | 0 | case PPC::BI__builtin_pdepd: |
3912 | 0 | case PPC::BI__builtin_pextd: |
3913 | 0 | case PPC::BI__builtin_ppc_ldarx: |
3914 | 0 | case PPC::BI__builtin_ppc_stdcx: |
3915 | 0 | case PPC::BI__builtin_ppc_tdw: |
3916 | 0 | case PPC::BI__builtin_ppc_trapd: |
3917 | 0 | case PPC::BI__builtin_ppc_cmpeqb: |
3918 | 0 | case PPC::BI__builtin_ppc_setb: |
3919 | 0 | case PPC::BI__builtin_ppc_mulhd: |
3920 | 0 | case PPC::BI__builtin_ppc_mulhdu: |
3921 | 0 | case PPC::BI__builtin_ppc_maddhd: |
3922 | 0 | case PPC::BI__builtin_ppc_maddhdu: |
3923 | 0 | case PPC::BI__builtin_ppc_maddld: |
3924 | 0 | case PPC::BI__builtin_ppc_load8r: |
3925 | 0 | case PPC::BI__builtin_ppc_store8r: |
3926 | 0 | case PPC::BI__builtin_ppc_insert_exp: |
3927 | 0 | case PPC::BI__builtin_ppc_extract_sig: |
3928 | 0 | case PPC::BI__builtin_ppc_addex: |
3929 | 0 | case PPC::BI__builtin_darn: |
3930 | 0 | case PPC::BI__builtin_darn_raw: |
3931 | 0 | case PPC::BI__builtin_ppc_compare_and_swaplp: |
3932 | 0 | case PPC::BI__builtin_ppc_fetch_and_addlp: |
3933 | 0 | case PPC::BI__builtin_ppc_fetch_and_andlp: |
3934 | 0 | case PPC::BI__builtin_ppc_fetch_and_orlp: |
3935 | 0 | case PPC::BI__builtin_ppc_fetch_and_swaplp: |
3936 | 0 | return true; |
3937 | 16.9k | } |
3938 | 16.9k | return false; |
3939 | 16.9k | } |
3940 | | |
3941 | | static bool SemaFeatureCheck(Sema &S, CallExpr *TheCall, |
3942 | | StringRef FeatureToCheck, unsigned DiagID, |
3943 | 476 | StringRef DiagArg = "") { |
3944 | 476 | if (S.Context.getTargetInfo().hasFeature(FeatureToCheck)) |
3945 | 476 | return false; |
3946 | | |
3947 | 0 | if (DiagArg.empty()) |
3948 | 0 | S.Diag(TheCall->getBeginLoc(), DiagID) << TheCall->getSourceRange(); |
3949 | 0 | else |
3950 | 0 | S.Diag(TheCall->getBeginLoc(), DiagID) |
3951 | 0 | << DiagArg << TheCall->getSourceRange(); |
3952 | |
|
3953 | 0 | return true; |
3954 | 476 | } |
3955 | | |
3956 | | /// Returns true if the argument consists of one contiguous run of 1s with any |
3957 | | /// number of 0s on either side. The 1s are allowed to wrap from LSB to MSB, so |
3958 | | /// 0x000FFF0, 0x0000FFFF, 0xFF0000FF, 0x0 are all runs. 0x0F0F0000 is not, |
3959 | | /// since all 1s are not contiguous. |
3960 | 0 | bool Sema::SemaValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum) { |
3961 | 0 | llvm::APSInt Result; |
3962 | | // We can't check the value of a dependent argument. |
3963 | 0 | Expr *Arg = TheCall->getArg(ArgNum); |
3964 | 0 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
3965 | 0 | return false; |
3966 | | |
3967 | | // Check constant-ness first. |
3968 | 0 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
3969 | 0 | return true; |
3970 | | |
3971 | | // Check contiguous run of 1s, 0xFF0000FF is also a run of 1s. |
3972 | 0 | if (Result.isShiftedMask() || (~Result).isShiftedMask()) |
3973 | 0 | return false; |
3974 | | |
3975 | 0 | return Diag(TheCall->getBeginLoc(), |
3976 | 0 | diag::err_argument_not_contiguous_bit_field) |
3977 | 0 | << ArgNum << Arg->getSourceRange(); |
3978 | 0 | } |
3979 | | |
3980 | | bool Sema::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, |
3981 | 16.9k | CallExpr *TheCall) { |
3982 | 16.9k | unsigned i = 0, l = 0, u = 0; |
3983 | 16.9k | bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64; |
3984 | 16.9k | llvm::APSInt Result; |
3985 | | |
3986 | 16.9k | if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit0 ) |
3987 | 0 | return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt) |
3988 | 0 | << TheCall->getSourceRange(); |
3989 | | |
3990 | 16.9k | switch (BuiltinID) { |
3991 | 16.6k | default: return false; |
3992 | 0 | case PPC::BI__builtin_altivec_crypto_vshasigmaw: |
3993 | 0 | case PPC::BI__builtin_altivec_crypto_vshasigmad: |
3994 | 0 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || |
3995 | 0 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 15); |
3996 | 0 | case PPC::BI__builtin_altivec_dss: |
3997 | 0 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 3); |
3998 | 4 | case PPC::BI__builtin_tbegin: |
3999 | 6 | case PPC::BI__builtin_tend: |
4000 | 6 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 1) || |
4001 | 6 | SemaFeatureCheck(*this, TheCall, "htm", |
4002 | 6 | diag::err_ppc_builtin_requires_htm); |
4003 | 0 | case PPC::BI__builtin_tsr: |
4004 | 0 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 7) || |
4005 | 0 | SemaFeatureCheck(*this, TheCall, "htm", |
4006 | 0 | diag::err_ppc_builtin_requires_htm); |
4007 | 0 | case PPC::BI__builtin_tabortwc: |
4008 | 0 | case PPC::BI__builtin_tabortdc: |
4009 | 0 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31) || |
4010 | 0 | SemaFeatureCheck(*this, TheCall, "htm", |
4011 | 0 | diag::err_ppc_builtin_requires_htm); |
4012 | 0 | case PPC::BI__builtin_tabortwci: |
4013 | 0 | case PPC::BI__builtin_tabortdci: |
4014 | 0 | return SemaFeatureCheck(*this, TheCall, "htm", |
4015 | 0 | diag::err_ppc_builtin_requires_htm) || |
4016 | 0 | (SemaBuiltinConstantArgRange(TheCall, 0, 0, 31) || |
4017 | 0 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 31)); |
4018 | 4 | case PPC::BI__builtin_tabort: |
4019 | 4 | case PPC::BI__builtin_tcheck: |
4020 | 4 | case PPC::BI__builtin_treclaim: |
4021 | 4 | case PPC::BI__builtin_trechkpt: |
4022 | 4 | case PPC::BI__builtin_tendall: |
4023 | 6 | case PPC::BI__builtin_tresume: |
4024 | 8 | case PPC::BI__builtin_tsuspend: |
4025 | 12 | case PPC::BI__builtin_get_texasr: |
4026 | 12 | case PPC::BI__builtin_get_texasru: |
4027 | 12 | case PPC::BI__builtin_get_tfhar: |
4028 | 14 | case PPC::BI__builtin_get_tfiar: |
4029 | 14 | case PPC::BI__builtin_set_texasr: |
4030 | 14 | case PPC::BI__builtin_set_texasru: |
4031 | 14 | case PPC::BI__builtin_set_tfhar: |
4032 | 14 | case PPC::BI__builtin_set_tfiar: |
4033 | 16 | case PPC::BI__builtin_ttest: |
4034 | 16 | return SemaFeatureCheck(*this, TheCall, "htm", |
4035 | 16 | diag::err_ppc_builtin_requires_htm); |
4036 | | // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05', |
4037 | | // __builtin_(un)pack_longdouble are available only if long double uses IBM |
4038 | | // extended double representation. |
4039 | 0 | case PPC::BI__builtin_unpack_longdouble: |
4040 | 0 | if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 1)) |
4041 | 0 | return true; |
4042 | 0 | LLVM_FALLTHROUGH; |
4043 | 0 | case PPC::BI__builtin_pack_longdouble: |
4044 | 0 | if (&TI.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble()) |
4045 | 0 | return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_requires_abi) |
4046 | 0 | << "ibmlongdouble"; |
4047 | 0 | return false; |
4048 | 0 | case PPC::BI__builtin_altivec_dst: |
4049 | 0 | case PPC::BI__builtin_altivec_dstt: |
4050 | 0 | case PPC::BI__builtin_altivec_dstst: |
4051 | 0 | case PPC::BI__builtin_altivec_dststt: |
4052 | 0 | return SemaBuiltinConstantArgRange(TheCall, 2, 0, 3); |
4053 | 0 | case PPC::BI__builtin_vsx_xxpermdi: |
4054 | 0 | case PPC::BI__builtin_vsx_xxsldwi: |
4055 | 0 | return SemaBuiltinVSX(TheCall); |
4056 | 0 | case PPC::BI__builtin_divwe: |
4057 | 0 | case PPC::BI__builtin_divweu: |
4058 | 0 | case PPC::BI__builtin_divde: |
4059 | 0 | case PPC::BI__builtin_divdeu: |
4060 | 0 | return SemaFeatureCheck(*this, TheCall, "extdiv", |
4061 | 0 | diag::err_ppc_builtin_only_on_arch, "7"); |
4062 | 0 | case PPC::BI__builtin_bpermd: |
4063 | 0 | return SemaFeatureCheck(*this, TheCall, "bpermd", |
4064 | 0 | diag::err_ppc_builtin_only_on_arch, "7"); |
4065 | 0 | case PPC::BI__builtin_unpack_vector_int128: |
4066 | 0 | return SemaFeatureCheck(*this, TheCall, "vsx", |
4067 | 0 | diag::err_ppc_builtin_only_on_arch, "7") || |
4068 | 0 | SemaBuiltinConstantArgRange(TheCall, 1, 0, 1); |
4069 | 0 | case PPC::BI__builtin_pack_vector_int128: |
4070 | 0 | return SemaFeatureCheck(*this, TheCall, "vsx", |
4071 | 0 | diag::err_ppc_builtin_only_on_arch, "7"); |
4072 | 0 | case PPC::BI__builtin_pdepd: |
4073 | 0 | case PPC::BI__builtin_pextd: |
4074 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v31-instructions", |
4075 | 0 | diag::err_ppc_builtin_only_on_arch, "10"); |
4076 | 0 | case PPC::BI__builtin_altivec_vgnb: |
4077 | 0 | return SemaBuiltinConstantArgRange(TheCall, 1, 2, 7); |
4078 | 0 | case PPC::BI__builtin_vsx_xxeval: |
4079 | 0 | return SemaBuiltinConstantArgRange(TheCall, 3, 0, 255); |
4080 | 0 | case PPC::BI__builtin_altivec_vsldbi: |
4081 | 0 | return SemaBuiltinConstantArgRange(TheCall, 2, 0, 7); |
4082 | 0 | case PPC::BI__builtin_altivec_vsrdbi: |
4083 | 0 | return SemaBuiltinConstantArgRange(TheCall, 2, 0, 7); |
4084 | 0 | case PPC::BI__builtin_vsx_xxpermx: |
4085 | 0 | return SemaBuiltinConstantArgRange(TheCall, 3, 0, 7); |
4086 | 0 | case PPC::BI__builtin_ppc_tw: |
4087 | 0 | case PPC::BI__builtin_ppc_tdw: |
4088 | 0 | return SemaBuiltinConstantArgRange(TheCall, 2, 1, 31); |
4089 | 0 | case PPC::BI__builtin_ppc_cmpeqb: |
4090 | 0 | case PPC::BI__builtin_ppc_setb: |
4091 | 0 | case PPC::BI__builtin_ppc_maddhd: |
4092 | 0 | case PPC::BI__builtin_ppc_maddhdu: |
4093 | 0 | case PPC::BI__builtin_ppc_maddld: |
4094 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions", |
4095 | 0 | diag::err_ppc_builtin_only_on_arch, "9"); |
4096 | 0 | case PPC::BI__builtin_ppc_cmprb: |
4097 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions", |
4098 | 0 | diag::err_ppc_builtin_only_on_arch, "9") || |
4099 | 0 | SemaBuiltinConstantArgRange(TheCall, 0, 0, 1); |
4100 | | // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must |
4101 | | // be a constant that represents a contiguous bit field. |
4102 | 0 | case PPC::BI__builtin_ppc_rlwnm: |
4103 | 0 | return SemaValueIsRunOfOnes(TheCall, 2); |
4104 | 0 | case PPC::BI__builtin_ppc_rlwimi: |
4105 | 0 | case PPC::BI__builtin_ppc_rldimi: |
4106 | 0 | return SemaBuiltinConstantArg(TheCall, 2, Result) || |
4107 | 0 | SemaValueIsRunOfOnes(TheCall, 3); |
4108 | 0 | case PPC::BI__builtin_ppc_extract_exp: |
4109 | 0 | case PPC::BI__builtin_ppc_extract_sig: |
4110 | 0 | case PPC::BI__builtin_ppc_insert_exp: |
4111 | 0 | return SemaFeatureCheck(*this, TheCall, "power9-vector", |
4112 | 0 | diag::err_ppc_builtin_only_on_arch, "9"); |
4113 | 0 | case PPC::BI__builtin_ppc_addex: { |
4114 | 0 | if (SemaFeatureCheck(*this, TheCall, "isa-v30-instructions", |
4115 | 0 | diag::err_ppc_builtin_only_on_arch, "9") || |
4116 | 0 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 3)) |
4117 | 0 | return true; |
4118 | | // Output warning for reserved values 1 to 3. |
4119 | 0 | int ArgValue = |
4120 | 0 | TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue(); |
4121 | 0 | if (ArgValue != 0) |
4122 | 0 | Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour) |
4123 | 0 | << ArgValue; |
4124 | 0 | return false; |
4125 | 0 | } |
4126 | 4 | case PPC::BI__builtin_ppc_mtfsb0: |
4127 | 8 | case PPC::BI__builtin_ppc_mtfsb1: |
4128 | 8 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31); |
4129 | 4 | case PPC::BI__builtin_ppc_mtfsf: |
4130 | 4 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 255); |
4131 | 4 | case PPC::BI__builtin_ppc_mtfsfi: |
4132 | 4 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 7) || |
4133 | 4 | SemaBuiltinConstantArgRange(TheCall, 1, 0, 15); |
4134 | 0 | case PPC::BI__builtin_ppc_alignx: |
4135 | 0 | return SemaBuiltinConstantArgPower2(TheCall, 0); |
4136 | 0 | case PPC::BI__builtin_ppc_rdlam: |
4137 | 0 | return SemaValueIsRunOfOnes(TheCall, 2); |
4138 | 0 | case PPC::BI__builtin_ppc_icbt: |
4139 | 0 | case PPC::BI__builtin_ppc_sthcx: |
4140 | 0 | case PPC::BI__builtin_ppc_stbcx: |
4141 | 0 | case PPC::BI__builtin_ppc_lharx: |
4142 | 0 | case PPC::BI__builtin_ppc_lbarx: |
4143 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v207-instructions", |
4144 | 0 | diag::err_ppc_builtin_only_on_arch, "8"); |
4145 | 0 | case PPC::BI__builtin_vsx_ldrmb: |
4146 | 0 | case PPC::BI__builtin_vsx_strmb: |
4147 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v207-instructions", |
4148 | 0 | diag::err_ppc_builtin_only_on_arch, "8") || |
4149 | 0 | SemaBuiltinConstantArgRange(TheCall, 1, 1, 16); |
4150 | 0 | case PPC::BI__builtin_altivec_vcntmbb: |
4151 | 0 | case PPC::BI__builtin_altivec_vcntmbh: |
4152 | 0 | case PPC::BI__builtin_altivec_vcntmbw: |
4153 | 0 | case PPC::BI__builtin_altivec_vcntmbd: |
4154 | 0 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1); |
4155 | 0 | case PPC::BI__builtin_darn: |
4156 | 0 | case PPC::BI__builtin_darn_raw: |
4157 | 0 | case PPC::BI__builtin_darn_32: |
4158 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions", |
4159 | 0 | diag::err_ppc_builtin_only_on_arch, "9"); |
4160 | 0 | case PPC::BI__builtin_vsx_xxgenpcvbm: |
4161 | 0 | case PPC::BI__builtin_vsx_xxgenpcvhm: |
4162 | 0 | case PPC::BI__builtin_vsx_xxgenpcvwm: |
4163 | 0 | case PPC::BI__builtin_vsx_xxgenpcvdm: |
4164 | 0 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3); |
4165 | 0 | case PPC::BI__builtin_ppc_compare_exp_uo: |
4166 | 0 | case PPC::BI__builtin_ppc_compare_exp_lt: |
4167 | 0 | case PPC::BI__builtin_ppc_compare_exp_gt: |
4168 | 0 | case PPC::BI__builtin_ppc_compare_exp_eq: |
4169 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions", |
4170 | 0 | diag::err_ppc_builtin_only_on_arch, "9") || |
4171 | 0 | SemaFeatureCheck(*this, TheCall, "vsx", |
4172 | 0 | diag::err_ppc_builtin_requires_vsx); |
4173 | 0 | case PPC::BI__builtin_ppc_test_data_class: { |
4174 | | // Check if the first argument of the __builtin_ppc_test_data_class call is |
4175 | | // valid. The argument must be either a 'float' or a 'double'. |
4176 | 0 | QualType ArgType = TheCall->getArg(0)->getType(); |
4177 | 0 | if (ArgType != QualType(Context.FloatTy) && |
4178 | 0 | ArgType != QualType(Context.DoubleTy)) |
4179 | 0 | return Diag(TheCall->getBeginLoc(), |
4180 | 0 | diag::err_ppc_invalid_test_data_class_type); |
4181 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v30-instructions", |
4182 | 0 | diag::err_ppc_builtin_only_on_arch, "9") || |
4183 | 0 | SemaFeatureCheck(*this, TheCall, "vsx", |
4184 | 0 | diag::err_ppc_builtin_requires_vsx) || |
4185 | 0 | SemaBuiltinConstantArgRange(TheCall, 1, 0, 127); |
4186 | 0 | } |
4187 | 0 | case PPC::BI__builtin_ppc_maxfe: |
4188 | 0 | case PPC::BI__builtin_ppc_minfe: |
4189 | 0 | case PPC::BI__builtin_ppc_maxfl: |
4190 | 0 | case PPC::BI__builtin_ppc_minfl: |
4191 | 0 | case PPC::BI__builtin_ppc_maxfs: |
4192 | 0 | case PPC::BI__builtin_ppc_minfs: { |
4193 | 0 | if (Context.getTargetInfo().getTriple().isOSAIX() && |
4194 | 0 | (BuiltinID == PPC::BI__builtin_ppc_maxfe || |
4195 | 0 | BuiltinID == PPC::BI__builtin_ppc_minfe)) |
4196 | 0 | return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type) |
4197 | 0 | << "builtin" << true << 128 << QualType(Context.LongDoubleTy) |
4198 | 0 | << false << Context.getTargetInfo().getTriple().str(); |
4199 | | // Argument type should be exact. |
4200 | 0 | QualType ArgType = QualType(Context.LongDoubleTy); |
4201 | 0 | if (BuiltinID == PPC::BI__builtin_ppc_maxfl || |
4202 | 0 | BuiltinID == PPC::BI__builtin_ppc_minfl) |
4203 | 0 | ArgType = QualType(Context.DoubleTy); |
4204 | 0 | else if (BuiltinID == PPC::BI__builtin_ppc_maxfs || |
4205 | 0 | BuiltinID == PPC::BI__builtin_ppc_minfs) |
4206 | 0 | ArgType = QualType(Context.FloatTy); |
4207 | 0 | for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I) |
4208 | 0 | if (TheCall->getArg(I)->getType() != ArgType) |
4209 | 0 | return Diag(TheCall->getBeginLoc(), |
4210 | 0 | diag::err_typecheck_convert_incompatible) |
4211 | 0 | << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0; |
4212 | 0 | return false; |
4213 | 0 | } |
4214 | 0 | case PPC::BI__builtin_ppc_load8r: |
4215 | 0 | case PPC::BI__builtin_ppc_store8r: |
4216 | 0 | return SemaFeatureCheck(*this, TheCall, "isa-v206-instructions", |
4217 | 0 | diag::err_ppc_builtin_only_on_arch, "7"); |
4218 | 0 | #define CUSTOM_BUILTIN(Name, Intr, Types, Acc) \ |
4219 | 254 | case PPC::BI__builtin_##Name: \ |
4220 | 254 | return SemaBuiltinPPCMMACall(TheCall, BuiltinID, Types); |
4221 | 16.9k | #include "clang/Basic/BuiltinsPPC.def"0 |
4222 | 16.9k | } |
4223 | 0 | return SemaBuiltinConstantArgRange(TheCall, i, l, u); |
4224 | 16.9k | } |
4225 | | |
4226 | | // Check if the given type is a non-pointer PPC MMA type. This function is used |
4227 | | // in Sema to prevent invalid uses of restricted PPC MMA types. |
4228 | 161k | bool Sema::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) { |
4229 | 161k | if (Type->isPointerType() || Type->isArrayType()153k ) |
4230 | 10.8k | return false; |
4231 | | |
4232 | 151k | QualType CoreType = Type.getCanonicalType().getUnqualifiedType(); |
4233 | 302k | #define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id302k ##Ty |
4234 | 151k | if (false |
4235 | 302k | #include "clang/Basic/PPCTypes.def"151k |
4236 | 151k | ) { |
4237 | 130 | Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type); |
4238 | 130 | return true; |
4239 | 130 | } |
4240 | 150k | return false; |
4241 | 151k | } |
4242 | | |
4243 | | bool Sema::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, |
4244 | 712 | CallExpr *TheCall) { |
4245 | | // position of memory order and scope arguments in the builtin |
4246 | 712 | unsigned OrderIndex, ScopeIndex; |
4247 | 712 | switch (BuiltinID) { |
4248 | 17 | case AMDGPU::BI__builtin_amdgcn_atomic_inc32: |
4249 | 33 | case AMDGPU::BI__builtin_amdgcn_atomic_inc64: |
4250 | 52 | case AMDGPU::BI__builtin_amdgcn_atomic_dec32: |
4251 | 72 | case AMDGPU::BI__builtin_amdgcn_atomic_dec64: |
4252 | 72 | OrderIndex = 2; |
4253 | 72 | ScopeIndex = 3; |
4254 | 72 | break; |
4255 | 11 | case AMDGPU::BI__builtin_amdgcn_fence: |
4256 | 11 | OrderIndex = 0; |
4257 | 11 | ScopeIndex = 1; |
4258 | 11 | break; |
4259 | 629 | default: |
4260 | 629 | return false; |
4261 | 712 | } |
4262 | | |
4263 | 83 | ExprResult Arg = TheCall->getArg(OrderIndex); |
4264 | 83 | auto ArgExpr = Arg.get(); |
4265 | 83 | Expr::EvalResult ArgResult; |
4266 | | |
4267 | 83 | if (!ArgExpr->EvaluateAsInt(ArgResult, Context)) |
4268 | 0 | return Diag(ArgExpr->getExprLoc(), diag::err_typecheck_expect_int) |
4269 | 0 | << ArgExpr->getType(); |
4270 | 83 | auto Ord = ArgResult.Val.getInt().getZExtValue(); |
4271 | | |
4272 | | // Check validity of memory ordering as per C11 / C++11's memody model. |
4273 | | // Only fence needs check. Atomic dec/inc allow all memory orders. |
4274 | 83 | if (!llvm::isValidAtomicOrderingCABI(Ord)) |
4275 | 5 | return Diag(ArgExpr->getBeginLoc(), |
4276 | 5 | diag::warn_atomic_op_has_invalid_memory_order) |
4277 | 5 | << ArgExpr->getSourceRange(); |
4278 | 78 | switch (static_cast<llvm::AtomicOrderingCABI>(Ord)) { |
4279 | 6 | case llvm::AtomicOrderingCABI::relaxed: |
4280 | 13 | case llvm::AtomicOrderingCABI::consume: |
4281 | 13 | if (BuiltinID == AMDGPU::BI__builtin_amdgcn_fence) |
4282 | 1 | return Diag(ArgExpr->getBeginLoc(), |
4283 | 1 | diag::warn_atomic_op_has_invalid_memory_order) |
4284 | 1 | << ArgExpr->getSourceRange(); |
4285 | 12 | break; |
4286 | 17 | case llvm::AtomicOrderingCABI::acquire: |
4287 | 25 | case llvm::AtomicOrderingCABI::release: |
4288 | 28 | case llvm::AtomicOrderingCABI::acq_rel: |
4289 | 65 | case llvm::AtomicOrderingCABI::seq_cst: |
4290 | 65 | break; |
4291 | 78 | } |
4292 | | |
4293 | 77 | Arg = TheCall->getArg(ScopeIndex); |
4294 | 77 | ArgExpr = Arg.get(); |
4295 | 77 | Expr::EvalResult ArgResult1; |
4296 | | // Check that sync scope is a constant literal |
4297 | 77 | if (!ArgExpr->EvaluateAsConstantExpr(ArgResult1, Context)) |
4298 | 5 | return Diag(ArgExpr->getExprLoc(), diag::err_expr_not_string_literal) |
4299 | 5 | << ArgExpr->getType(); |
4300 | | |
4301 | 72 | return false; |
4302 | 77 | } |
4303 | | |
4304 | 4 | bool Sema::CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum) { |
4305 | 4 | llvm::APSInt Result; |
4306 | | |
4307 | | // We can't check the value of a dependent argument. |
4308 | 4 | Expr *Arg = TheCall->getArg(ArgNum); |
4309 | 4 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
4310 | 0 | return false; |
4311 | | |
4312 | | // Check constant-ness first. |
4313 | 4 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
4314 | 0 | return true; |
4315 | | |
4316 | 4 | int64_t Val = Result.getSExtValue(); |
4317 | 4 | if ((Val >= 0 && Val <= 33 ) || (Val >= 5 && Val <= 71 )) |
4318 | 0 | return false; |
4319 | | |
4320 | 4 | return Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_invalid_lmul) |
4321 | 4 | << Arg->getSourceRange(); |
4322 | 4 | } |
4323 | | |
4324 | 80 | static bool isRISCV32Builtin(unsigned BuiltinID) { |
4325 | | // These builtins only work on riscv32 targets. |
4326 | 80 | switch (BuiltinID) { |
4327 | 0 | case RISCV::BI__builtin_riscv_zip_32: |
4328 | 0 | case RISCV::BI__builtin_riscv_unzip_32: |
4329 | 0 | case RISCV::BI__builtin_riscv_aes32dsi_32: |
4330 | 0 | case RISCV::BI__builtin_riscv_aes32dsmi_32: |
4331 | 0 | case RISCV::BI__builtin_riscv_aes32esi_32: |
4332 | 0 | case RISCV::BI__builtin_riscv_aes32esmi_32: |
4333 | 0 | case RISCV::BI__builtin_riscv_sha512sig0h_32: |
4334 | 0 | case RISCV::BI__builtin_riscv_sha512sig0l_32: |
4335 | 0 | case RISCV::BI__builtin_riscv_sha512sig1h_32: |
4336 | 0 | case RISCV::BI__builtin_riscv_sha512sig1l_32: |
4337 | 0 | case RISCV::BI__builtin_riscv_sha512sum0r_32: |
4338 | 0 | case RISCV::BI__builtin_riscv_sha512sum1r_32: |
4339 | 0 | return true; |
4340 | 80 | } |
4341 | | |
4342 | 80 | return false; |
4343 | 80 | } |
4344 | | |
4345 | | bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, |
4346 | | unsigned BuiltinID, |
4347 | 135 | CallExpr *TheCall) { |
4348 | | // CodeGenFunction can also detect this, but this gives a better error |
4349 | | // message. |
4350 | 135 | bool FeatureMissing = false; |
4351 | 135 | SmallVector<StringRef> ReqFeatures; |
4352 | 135 | StringRef Features = Context.BuiltinInfo.getRequiredFeatures(BuiltinID); |
4353 | 135 | Features.split(ReqFeatures, ','); |
4354 | | |
4355 | | // Check for 32-bit only builtins on a 64-bit target. |
4356 | 135 | const llvm::Triple &TT = TI.getTriple(); |
4357 | 135 | if (TT.getArch() != llvm::Triple::riscv32 && isRISCV32Builtin(BuiltinID)80 ) |
4358 | 0 | return Diag(TheCall->getCallee()->getBeginLoc(), |
4359 | 0 | diag::err_32_bit_builtin_64_bit_tgt); |
4360 | | |
4361 | | // Check if each required feature is included |
4362 | 169 | for (StringRef F : ReqFeatures)135 { |
4363 | 169 | SmallVector<StringRef> ReqOpFeatures; |
4364 | 169 | F.split(ReqOpFeatures, '|'); |
4365 | 169 | bool HasFeature = false; |
4366 | 181 | for (StringRef OF : ReqOpFeatures) { |
4367 | 181 | if (TI.hasFeature(OF)) { |
4368 | 168 | HasFeature = true; |
4369 | 168 | continue; |
4370 | 168 | } |
4371 | 181 | } |
4372 | | |
4373 | 169 | if (!HasFeature) { |
4374 | 1 | std::string FeatureStrs; |
4375 | 1 | for (StringRef OF : ReqOpFeatures) { |
4376 | | // If the feature is 64bit, alter the string so it will print better in |
4377 | | // the diagnostic. |
4378 | 1 | if (OF == "64bit") |
4379 | 1 | OF = "RV64"; |
4380 | | |
4381 | | // Convert features like "zbr" and "experimental-zbr" to "Zbr". |
4382 | 1 | OF.consume_front("experimental-"); |
4383 | 1 | std::string FeatureStr = OF.str(); |
4384 | 1 | FeatureStr[0] = std::toupper(FeatureStr[0]); |
4385 | | // Combine strings. |
4386 | 1 | FeatureStrs += FeatureStrs == "" ? "" : ", "0 ; |
4387 | 1 | FeatureStrs += "'"; |
4388 | 1 | FeatureStrs += FeatureStr; |
4389 | 1 | FeatureStrs += "'"; |
4390 | 1 | } |
4391 | | // Error message |
4392 | 1 | FeatureMissing = true; |
4393 | 1 | Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension) |
4394 | 1 | << TheCall->getSourceRange() << StringRef(FeatureStrs); |
4395 | 1 | } |
4396 | 169 | } |
4397 | | |
4398 | 135 | if (FeatureMissing) |
4399 | 1 | return true; |
4400 | | |
4401 | 134 | switch (BuiltinID) { |
4402 | 3 | case RISCVVector::BI__builtin_rvv_vsetvli: |
4403 | 3 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3) || |
4404 | 3 | CheckRISCVLMUL(TheCall, 2)2 ; |
4405 | 3 | case RISCVVector::BI__builtin_rvv_vsetvlimax: |
4406 | 3 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 3) || |
4407 | 3 | CheckRISCVLMUL(TheCall, 1)2 ; |
4408 | 0 | case RISCVVector::BI__builtin_rvv_vget_v: { |
4409 | 0 | ASTContext::BuiltinVectorTypeInfo ResVecInfo = |
4410 | 0 | Context.getBuiltinVectorTypeInfo(cast<BuiltinType>( |
4411 | 0 | TheCall->getType().getCanonicalType().getTypePtr())); |
4412 | 0 | ASTContext::BuiltinVectorTypeInfo VecInfo = |
4413 | 0 | Context.getBuiltinVectorTypeInfo(cast<BuiltinType>( |
4414 | 0 | TheCall->getArg(0)->getType().getCanonicalType().getTypePtr())); |
4415 | 0 | unsigned MaxIndex = |
4416 | 0 | (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors) / |
4417 | 0 | (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors); |
4418 | 0 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1); |
4419 | 0 | } |
4420 | 0 | case RISCVVector::BI__builtin_rvv_vset_v: { |
4421 | 0 | ASTContext::BuiltinVectorTypeInfo ResVecInfo = |
4422 | 0 | Context.getBuiltinVectorTypeInfo(cast<BuiltinType>( |
4423 | 0 | TheCall->getType().getCanonicalType().getTypePtr())); |
4424 | 0 | ASTContext::BuiltinVectorTypeInfo VecInfo = |
4425 | 0 | Context.getBuiltinVectorTypeInfo(cast<BuiltinType>( |
4426 | 0 | TheCall->getArg(2)->getType().getCanonicalType().getTypePtr())); |
4427 | 0 | unsigned MaxIndex = |
4428 | 0 | (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors) / |
4429 | 0 | (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors); |
4430 | 0 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1); |
4431 | 0 | } |
4432 | | // Check if byteselect is in [0, 3] |
4433 | 1 | case RISCV::BI__builtin_riscv_aes32dsi_32: |
4434 | 2 | case RISCV::BI__builtin_riscv_aes32dsmi_32: |
4435 | 3 | case RISCV::BI__builtin_riscv_aes32esi_32: |
4436 | 4 | case RISCV::BI__builtin_riscv_aes32esmi_32: |
4437 | 6 | case RISCV::BI__builtin_riscv_sm4ks: |
4438 | 8 | case RISCV::BI__builtin_riscv_sm4ed: |
4439 | 8 | return SemaBuiltinConstantArgRange(TheCall, 2, 0, 3); |
4440 | | // Check if rnum is in [0, 10] |
4441 | 2 | case RISCV::BI__builtin_riscv_aes64ks1i_64: |
4442 | 2 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 10); |
4443 | 134 | } |
4444 | | |
4445 | 118 | return false; |
4446 | 134 | } |
4447 | | |
4448 | | bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, |
4449 | 0 | CallExpr *TheCall) { |
4450 | 0 | if (BuiltinID == SystemZ::BI__builtin_tabort) { |
4451 | 0 | Expr *Arg = TheCall->getArg(0); |
4452 | 0 | if (Optional<llvm::APSInt> AbortCode = Arg->getIntegerConstantExpr(Context)) |
4453 | 0 | if (AbortCode->getSExtValue() >= 0 && AbortCode->getSExtValue() < 256) |
4454 | 0 | return Diag(Arg->getBeginLoc(), diag::err_systemz_invalid_tabort_code) |
4455 | 0 | << Arg->getSourceRange(); |
4456 | 0 | } |
4457 | | |
4458 | | // For intrinsics which take an immediate value as part of the instruction, |
4459 | | // range check them here. |
4460 | 0 | unsigned i = 0, l = 0, u = 0; |
4461 | 0 | switch (BuiltinID) { |
4462 | 0 | default: return false; |
4463 | 0 | case SystemZ::BI__builtin_s390_lcbb: i = 1; l = 0; u = 15; break; |
4464 | 0 | case SystemZ::BI__builtin_s390_verimb: |
4465 | 0 | case SystemZ::BI__builtin_s390_verimh: |
4466 | 0 | case SystemZ::BI__builtin_s390_verimf: |
4467 | 0 | case SystemZ::BI__builtin_s390_verimg: i = 3; l = 0; u = 255; break; |
4468 | 0 | case SystemZ::BI__builtin_s390_vfaeb: |
4469 | 0 | case SystemZ::BI__builtin_s390_vfaeh: |
4470 | 0 | case SystemZ::BI__builtin_s390_vfaef: |
4471 | 0 | case SystemZ::BI__builtin_s390_vfaebs: |
4472 | 0 | case SystemZ::BI__builtin_s390_vfaehs: |
4473 | 0 | case SystemZ::BI__builtin_s390_vfaefs: |
4474 | 0 | case SystemZ::BI__builtin_s390_vfaezb: |
4475 | 0 | case SystemZ::BI__builtin_s390_vfaezh: |
4476 | 0 | case SystemZ::BI__builtin_s390_vfaezf: |
4477 | 0 | case SystemZ::BI__builtin_s390_vfaezbs: |
4478 | 0 | case SystemZ::BI__builtin_s390_vfaezhs: |
4479 | 0 | case SystemZ::BI__builtin_s390_vfaezfs: i = 2; l = 0; u = 15; break; |
4480 | 0 | case SystemZ::BI__builtin_s390_vfisb: |
4481 | 0 | case SystemZ::BI__builtin_s390_vfidb: |
4482 | 0 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15) || |
4483 | 0 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 15); |
4484 | 0 | case SystemZ::BI__builtin_s390_vftcisb: |
4485 | 0 | case SystemZ::BI__builtin_s390_vftcidb: i = 1; l = 0; u = 4095; break; |
4486 | 0 | case SystemZ::BI__builtin_s390_vlbb: i = 1; l = 0; u = 15; break; |
4487 | 0 | case SystemZ::BI__builtin_s390_vpdi: i = 2; l = 0; u = 15; break; |
4488 | 0 | case SystemZ::BI__builtin_s390_vsldb: i = 2; l = 0; u = 15; break; |
4489 | 0 | case SystemZ::BI__builtin_s390_vstrcb: |
4490 | 0 | case SystemZ::BI__builtin_s390_vstrch: |
4491 | 0 | case SystemZ::BI__builtin_s390_vstrcf: |
4492 | 0 | case SystemZ::BI__builtin_s390_vstrczb: |
4493 | 0 | case SystemZ::BI__builtin_s390_vstrczh: |
4494 | 0 | case SystemZ::BI__builtin_s390_vstrczf: |
4495 | 0 | case SystemZ::BI__builtin_s390_vstrcbs: |
4496 | 0 | case SystemZ::BI__builtin_s390_vstrchs: |
4497 | 0 | case SystemZ::BI__builtin_s390_vstrcfs: |
4498 | 0 | case SystemZ::BI__builtin_s390_vstrczbs: |
4499 | 0 | case SystemZ::BI__builtin_s390_vstrczhs: |
4500 | 0 | case SystemZ::BI__builtin_s390_vstrczfs: i = 3; l = 0; u = 15; break; |
4501 | 0 | case SystemZ::BI__builtin_s390_vmslg: i = 3; l = 0; u = 15; break; |
4502 | 0 | case SystemZ::BI__builtin_s390_vfminsb: |
4503 | 0 | case SystemZ::BI__builtin_s390_vfmaxsb: |
4504 | 0 | case SystemZ::BI__builtin_s390_vfmindb: |
4505 | 0 | case SystemZ::BI__builtin_s390_vfmaxdb: i = 2; l = 0; u = 15; break; |
4506 | 0 | case SystemZ::BI__builtin_s390_vsld: i = 2; l = 0; u = 7; break; |
4507 | 0 | case SystemZ::BI__builtin_s390_vsrd: i = 2; l = 0; u = 7; break; |
4508 | 0 | case SystemZ::BI__builtin_s390_vclfnhs: |
4509 | 0 | case SystemZ::BI__builtin_s390_vclfnls: |
4510 | 0 | case SystemZ::BI__builtin_s390_vcfn: |
4511 | 0 | case SystemZ::BI__builtin_s390_vcnf: i = 1; l = 0; u = 15; break; |
4512 | 0 | case SystemZ::BI__builtin_s390_vcrnfs: i = 2; l = 0; u = 15; break; |
4513 | 0 | } |
4514 | 0 | return SemaBuiltinConstantArgRange(TheCall, i, l, u); |
4515 | 0 | } |
4516 | | |
4517 | | /// SemaBuiltinCpuSupports - Handle __builtin_cpu_supports(char *). |
4518 | | /// This checks that the target supports __builtin_cpu_supports and |
4519 | | /// that the string argument is constant and valid. |
4520 | | static bool SemaBuiltinCpuSupports(Sema &S, const TargetInfo &TI, |
4521 | 44 | CallExpr *TheCall) { |
4522 | 44 | Expr *Arg = TheCall->getArg(0); |
4523 | | |
4524 | | // Check if the argument is a string literal. |
4525 | 44 | if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts())) |
4526 | 1 | return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal) |
4527 | 1 | << Arg->getSourceRange(); |
4528 | | |
4529 | | // Check the contents of the string. |
4530 | 43 | StringRef Feature = |
4531 | 43 | cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString(); |
4532 | 43 | if (!TI.validateCpuSupports(Feature)) |
4533 | 1 | return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_supports) |
4534 | 1 | << Arg->getSourceRange(); |
4535 | 42 | return false; |
4536 | 43 | } |
4537 | | |
4538 | | /// SemaBuiltinCpuIs - Handle __builtin_cpu_is(char *). |
4539 | | /// This checks that the target supports __builtin_cpu_is and |
4540 | | /// that the string argument is constant and valid. |
4541 | 58 | static bool SemaBuiltinCpuIs(Sema &S, const TargetInfo &TI, CallExpr *TheCall) { |
4542 | 58 | Expr *Arg = TheCall->getArg(0); |
4543 | | |
4544 | | // Check if the argument is a string literal. |
4545 | 58 | if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts())) |
4546 | 0 | return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal) |
4547 | 0 | << Arg->getSourceRange(); |
4548 | | |
4549 | | // Check the contents of the string. |
4550 | 58 | StringRef Feature = |
4551 | 58 | cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString(); |
4552 | 58 | if (!TI.validateCpuIs(Feature)) |
4553 | 6 | return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_is) |
4554 | 6 | << Arg->getSourceRange(); |
4555 | 52 | return false; |
4556 | 58 | } |
4557 | | |
4558 | | // Check if the rounding mode is legal. |
4559 | 1.00M | bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { |
4560 | | // Indicates if this instruction has rounding control or just SAE. |
4561 | 1.00M | bool HasRC = false; |
4562 | | |
4563 | 1.00M | unsigned ArgNum = 0; |
4564 | 1.00M | switch (BuiltinID) { |
4565 | 947k | default: |
4566 | 947k | return false; |
4567 | 299 | case X86::BI__builtin_ia32_vcvttsd2si32: |
4568 | 514 | case X86::BI__builtin_ia32_vcvttsd2si64: |
4569 | 811 | case X86::BI__builtin_ia32_vcvttsd2usi32: |
4570 | 1.02k | case X86::BI__builtin_ia32_vcvttsd2usi64: |
4571 | 1.32k | case X86::BI__builtin_ia32_vcvttss2si32: |
4572 | 1.53k | case X86::BI__builtin_ia32_vcvttss2si64: |
4573 | 1.83k | case X86::BI__builtin_ia32_vcvttss2usi32: |
4574 | 2.04k | case X86::BI__builtin_ia32_vcvttss2usi64: |
4575 | 2.05k | case X86::BI__builtin_ia32_vcvttsh2si32: |
4576 | 2.05k | case X86::BI__builtin_ia32_vcvttsh2si64: |
4577 | 2.05k | case X86::BI__builtin_ia32_vcvttsh2usi32: |
4578 | 2.06k | case X86::BI__builtin_ia32_vcvttsh2usi64: |
4579 | 2.06k | ArgNum = 1; |
4580 | 2.06k | break; |
4581 | 301 | case X86::BI__builtin_ia32_maxpd512: |
4582 | 602 | case X86::BI__builtin_ia32_maxps512: |
4583 | 903 | case X86::BI__builtin_ia32_minpd512: |
4584 | 1.20k | case X86::BI__builtin_ia32_minps512: |
4585 | 1.20k | case X86::BI__builtin_ia32_maxph512: |
4586 | 1.21k | case X86::BI__builtin_ia32_minph512: |
4587 | 1.21k | ArgNum = 2; |
4588 | 1.21k | break; |
4589 | 9 | case X86::BI__builtin_ia32_vcvtph2pd512_mask: |
4590 | 18 | case X86::BI__builtin_ia32_vcvtph2psx512_mask: |
4591 | 24 | case X86::BI__builtin_ia32_cvtps2pd512_mask: |
4592 | 915 | case X86::BI__builtin_ia32_cvttpd2dq512_mask: |
4593 | 1.80k | case X86::BI__builtin_ia32_cvttpd2qq512_mask: |
4594 | 2.69k | case X86::BI__builtin_ia32_cvttpd2udq512_mask: |
4595 | 3.58k | case X86::BI__builtin_ia32_cvttpd2uqq512_mask: |
4596 | 4.47k | case X86::BI__builtin_ia32_cvttps2dq512_mask: |
4597 | 5.36k | case X86::BI__builtin_ia32_cvttps2qq512_mask: |
4598 | 6.25k | case X86::BI__builtin_ia32_cvttps2udq512_mask: |
4599 | 7.14k | case X86::BI__builtin_ia32_cvttps2uqq512_mask: |
4600 | 7.14k | case X86::BI__builtin_ia32_vcvttph2w512_mask: |
4601 | 7.15k | case X86::BI__builtin_ia32_vcvttph2uw512_mask: |
4602 | 7.16k | case X86::BI__builtin_ia32_vcvttph2dq512_mask: |
4603 | 7.17k | case X86::BI__builtin_ia32_vcvttph2udq512_mask: |
4604 | 7.18k | case X86::BI__builtin_ia32_vcvttph2qq512_mask: |
4605 | 7.19k | case X86::BI__builtin_ia32_vcvttph2uqq512_mask: |
4606 | 7.20k | case X86::BI__builtin_ia32_exp2pd_mask: |
4607 | 7.20k | case X86::BI__builtin_ia32_exp2ps_mask: |
4608 | 8.09k | case X86::BI__builtin_ia32_getexppd512_mask: |
4609 | 8.98k | case X86::BI__builtin_ia32_getexpps512_mask: |
4610 | 8.99k | case X86::BI__builtin_ia32_getexpph512_mask: |
4611 | 9.00k | case X86::BI__builtin_ia32_rcp28pd_mask: |
4612 | 9.00k | case X86::BI__builtin_ia32_rcp28ps_mask: |
4613 | 9.01k | case X86::BI__builtin_ia32_rsqrt28pd_mask: |
4614 | 9.02k | case X86::BI__builtin_ia32_rsqrt28ps_mask: |
4615 | 9.02k | case X86::BI__builtin_ia32_vcomisd: |
4616 | 9.02k | case X86::BI__builtin_ia32_vcomiss: |
4617 | 9.05k | case X86::BI__builtin_ia32_vcomish: |
4618 | 9.96k | case X86::BI__builtin_ia32_vcvtph2ps512_mask: |
4619 | 9.96k | ArgNum = 3; |
4620 | 9.96k | break; |
4621 | 233 | case X86::BI__builtin_ia32_cmppd512_mask: |
4622 | 468 | case X86::BI__builtin_ia32_cmpps512_mask: |
4623 | 476 | case X86::BI__builtin_ia32_cmpsd_mask: |
4624 | 484 | case X86::BI__builtin_ia32_cmpss_mask: |
4625 | 488 | case X86::BI__builtin_ia32_cmpsh_mask: |
4626 | 497 | case X86::BI__builtin_ia32_vcvtsh2sd_round_mask: |
4627 | 506 | case X86::BI__builtin_ia32_vcvtsh2ss_round_mask: |
4628 | 1.10k | case X86::BI__builtin_ia32_cvtss2sd_round_mask: |
4629 | 1.99k | case X86::BI__builtin_ia32_getexpsd128_round_mask: |
4630 | 2.88k | case X86::BI__builtin_ia32_getexpss128_round_mask: |
4631 | 2.89k | case X86::BI__builtin_ia32_getexpsh128_round_mask: |
4632 | 2.90k | case X86::BI__builtin_ia32_getmantpd512_mask: |
4633 | 2.91k | case X86::BI__builtin_ia32_getmantps512_mask: |
4634 | 2.92k | case X86::BI__builtin_ia32_getmantph512_mask: |
4635 | 3.52k | case X86::BI__builtin_ia32_maxsd_round_mask: |
4636 | 4.11k | case X86::BI__builtin_ia32_maxss_round_mask: |
4637 | 4.12k | case X86::BI__builtin_ia32_maxsh_round_mask: |
4638 | 4.72k | case X86::BI__builtin_ia32_minsd_round_mask: |
4639 | 5.31k | case X86::BI__builtin_ia32_minss_round_mask: |
4640 | 5.32k | case X86::BI__builtin_ia32_minsh_round_mask: |
4641 | 5.33k | case X86::BI__builtin_ia32_rcp28sd_round_mask: |
4642 | 5.33k | case X86::BI__builtin_ia32_rcp28ss_round_mask: |
4643 | 5.34k | case X86::BI__builtin_ia32_reducepd512_mask: |
4644 | 5.35k | case X86::BI__builtin_ia32_reduceps512_mask: |
4645 | 5.35k | case X86::BI__builtin_ia32_reduceph512_mask: |
4646 | 6.54k | case X86::BI__builtin_ia32_rndscalepd_mask: |
4647 | 7.73k | case X86::BI__builtin_ia32_rndscaleps_mask: |
4648 | 7.74k | case X86::BI__builtin_ia32_rndscaleph_mask: |
4649 | 7.74k | case X86::BI__builtin_ia32_rsqrt28sd_round_mask: |
4650 | 7.75k | case X86::BI__builtin_ia32_rsqrt28ss_round_mask: |
4651 | 7.75k | ArgNum = 4; |
4652 | 7.75k | break; |
4653 | 8 | case X86::BI__builtin_ia32_fixupimmpd512_mask: |
4654 | 12 | case X86::BI__builtin_ia32_fixupimmpd512_maskz: |
4655 | 20 | case X86::BI__builtin_ia32_fixupimmps512_mask: |
4656 | 24 | case X86::BI__builtin_ia32_fixupimmps512_maskz: |
4657 | 32 | case X86::BI__builtin_ia32_fixupimmsd_mask: |
4658 | 36 | case X86::BI__builtin_ia32_fixupimmsd_maskz: |
4659 | 44 | case X86::BI__builtin_ia32_fixupimmss_mask: |
4660 | 48 | case X86::BI__builtin_ia32_fixupimmss_maskz: |
4661 | 60 | case X86::BI__builtin_ia32_getmantsd_round_mask: |
4662 | 73 | case X86::BI__builtin_ia32_getmantss_round_mask: |
4663 | 79 | case X86::BI__builtin_ia32_getmantsh_round_mask: |
4664 | 85 | case X86::BI__builtin_ia32_rangepd512_mask: |
4665 | 91 | case X86::BI__builtin_ia32_rangeps512_mask: |
4666 | 97 | case X86::BI__builtin_ia32_rangesd128_round_mask: |
4667 | 103 | case X86::BI__builtin_ia32_rangess128_round_mask: |
4668 | 109 | case X86::BI__builtin_ia32_reducesd_mask: |
4669 | 115 | case X86::BI__builtin_ia32_reducess_mask: |
4670 | 121 | case X86::BI__builtin_ia32_reducesh_mask: |
4671 | 133 | case X86::BI__builtin_ia32_rndscalesd_round_mask: |
4672 | 143 | case X86::BI__builtin_ia32_rndscaless_round_mask: |
4673 | 149 | case X86::BI__builtin_ia32_rndscalesh_round_mask: |
4674 | 149 | ArgNum = 5; |
4675 | 149 | break; |
4676 | 4 | case X86::BI__builtin_ia32_vcvtsd2si64: |
4677 | 8 | case X86::BI__builtin_ia32_vcvtsd2si32: |
4678 | 305 | case X86::BI__builtin_ia32_vcvtsd2usi32: |
4679 | 518 | case X86::BI__builtin_ia32_vcvtsd2usi64: |
4680 | 522 | case X86::BI__builtin_ia32_vcvtss2si32: |
4681 | 526 | case X86::BI__builtin_ia32_vcvtss2si64: |
4682 | 823 | case X86::BI__builtin_ia32_vcvtss2usi32: |
4683 | 1.03k | case X86::BI__builtin_ia32_vcvtss2usi64: |
4684 | 1.03k | case X86::BI__builtin_ia32_vcvtsh2si32: |
4685 | 1.04k | case X86::BI__builtin_ia32_vcvtsh2si64: |
4686 | 1.04k | case X86::BI__builtin_ia32_vcvtsh2usi32: |
4687 | 1.04k | case X86::BI__builtin_ia32_vcvtsh2usi64: |
4688 | 1.34k | case X86::BI__builtin_ia32_sqrtpd512: |
4689 | 1.65k | case X86::BI__builtin_ia32_sqrtps512: |
4690 | 1.65k | case X86::BI__builtin_ia32_sqrtph512: |
4691 | 1.65k | ArgNum = 1; |
4692 | 1.65k | HasRC = true; |
4693 | 1.65k | break; |
4694 | 3 | case X86::BI__builtin_ia32_addph512: |
4695 | 6 | case X86::BI__builtin_ia32_divph512: |
4696 | 9 | case X86::BI__builtin_ia32_mulph512: |
4697 | 12 | case X86::BI__builtin_ia32_subph512: |
4698 | 18 | case X86::BI__builtin_ia32_addpd512: |
4699 | 24 | case X86::BI__builtin_ia32_addps512: |
4700 | 30 | case X86::BI__builtin_ia32_divpd512: |
4701 | 36 | case X86::BI__builtin_ia32_divps512: |
4702 | 42 | case X86::BI__builtin_ia32_mulpd512: |
4703 | 48 | case X86::BI__builtin_ia32_mulps512: |
4704 | 54 | case X86::BI__builtin_ia32_subpd512: |
4705 | 60 | case X86::BI__builtin_ia32_subps512: |
4706 | 64 | case X86::BI__builtin_ia32_cvtsi2sd64: |
4707 | 68 | case X86::BI__builtin_ia32_cvtsi2ss32: |
4708 | 72 | case X86::BI__builtin_ia32_cvtsi2ss64: |
4709 | 74 | case X86::BI__builtin_ia32_cvtusi2sd64: |
4710 | 76 | case X86::BI__builtin_ia32_cvtusi2ss32: |
4711 | 78 | case X86::BI__builtin_ia32_cvtusi2ss64: |
4712 | 79 | case X86::BI__builtin_ia32_vcvtusi2sh: |
4713 | 80 | case X86::BI__builtin_ia32_vcvtusi642sh: |
4714 | 81 | case X86::BI__builtin_ia32_vcvtsi2sh: |
4715 | 82 | case X86::BI__builtin_ia32_vcvtsi642sh: |
4716 | 82 | ArgNum = 2; |
4717 | 82 | HasRC = true; |
4718 | 82 | break; |
4719 | 6 | case X86::BI__builtin_ia32_cvtdq2ps512_mask: |
4720 | 12 | case X86::BI__builtin_ia32_cvtudq2ps512_mask: |
4721 | 21 | case X86::BI__builtin_ia32_vcvtpd2ph512_mask: |
4722 | 30 | case X86::BI__builtin_ia32_vcvtps2phx512_mask: |
4723 | 921 | case X86::BI__builtin_ia32_cvtpd2ps512_mask: |
4724 | 1.81k | case X86::BI__builtin_ia32_cvtpd2dq512_mask: |
4725 | 2.70k | case X86::BI__builtin_ia32_cvtpd2qq512_mask: |
4726 | 3.59k | case X86::BI__builtin_ia32_cvtpd2udq512_mask: |
4727 | 4.47k | case X86::BI__builtin_ia32_cvtpd2uqq512_mask: |
4728 | 5.37k | case X86::BI__builtin_ia32_cvtps2dq512_mask: |
4729 | 6.25k | case X86::BI__builtin_ia32_cvtps2qq512_mask: |
4730 | 7.14k | case X86::BI__builtin_ia32_cvtps2udq512_mask: |
4731 | 8.03k | case X86::BI__builtin_ia32_cvtps2uqq512_mask: |
4732 | 8.05k | case X86::BI__builtin_ia32_cvtqq2pd512_mask: |
4733 | 8.95k | case X86::BI__builtin_ia32_cvtqq2ps512_mask: |
4734 | 8.96k | case X86::BI__builtin_ia32_cvtuqq2pd512_mask: |
4735 | 9.86k | case X86::BI__builtin_ia32_cvtuqq2ps512_mask: |
4736 | 9.87k | case X86::BI__builtin_ia32_vcvtdq2ph512_mask: |
4737 | 9.88k | case X86::BI__builtin_ia32_vcvtudq2ph512_mask: |
4738 | 9.89k | case X86::BI__builtin_ia32_vcvtw2ph512_mask: |
4739 | 9.90k | case X86::BI__builtin_ia32_vcvtuw2ph512_mask: |
4740 | 9.91k | case X86::BI__builtin_ia32_vcvtph2w512_mask: |
4741 | 9.92k | case X86::BI__builtin_ia32_vcvtph2uw512_mask: |
4742 | 9.93k | case X86::BI__builtin_ia32_vcvtph2dq512_mask: |
4743 | 9.93k | case X86::BI__builtin_ia32_vcvtph2udq512_mask: |
4744 | 9.94k | case X86::BI__builtin_ia32_vcvtph2qq512_mask: |
4745 | 9.95k | case X86::BI__builtin_ia32_vcvtph2uqq512_mask: |
4746 | 9.96k | case X86::BI__builtin_ia32_vcvtqq2ph512_mask: |
4747 | 9.97k | case X86::BI__builtin_ia32_vcvtuqq2ph512_mask: |
4748 | 9.97k | ArgNum = 3; |
4749 | 9.97k | HasRC = true; |
4750 | 9.97k | break; |
4751 | 3 | case X86::BI__builtin_ia32_addsh_round_mask: |
4752 | 9 | case X86::BI__builtin_ia32_addss_round_mask: |
4753 | 15 | case X86::BI__builtin_ia32_addsd_round_mask: |
4754 | 18 | case X86::BI__builtin_ia32_divsh_round_mask: |
4755 | 24 | case X86::BI__builtin_ia32_divss_round_mask: |
4756 | 30 | case X86::BI__builtin_ia32_divsd_round_mask: |
4757 | 33 | case X86::BI__builtin_ia32_mulsh_round_mask: |
4758 | 39 | case X86::BI__builtin_ia32_mulss_round_mask: |
4759 | 45 | case X86::BI__builtin_ia32_mulsd_round_mask: |
4760 | 48 | case X86::BI__builtin_ia32_subsh_round_mask: |
4761 | 54 | case X86::BI__builtin_ia32_subss_round_mask: |
4762 | 60 | case X86::BI__builtin_ia32_subsd_round_mask: |
4763 | 69 | case X86::BI__builtin_ia32_scalefph512_mask: |
4764 | 960 | case X86::BI__builtin_ia32_scalefpd512_mask: |
4765 | 1.85k | case X86::BI__builtin_ia32_scalefps512_mask: |
4766 | 2.74k | case X86::BI__builtin_ia32_scalefsd_round_mask: |
4767 | 3.63k | case X86::BI__builtin_ia32_scalefss_round_mask: |
4768 | 3.64k | case X86::BI__builtin_ia32_scalefsh_round_mask: |
4769 | 4.23k | case X86::BI__builtin_ia32_cvtsd2ss_round_mask: |
4770 | 4.24k | case X86::BI__builtin_ia32_vcvtss2sh_round_mask: |
4771 | 4.25k | case X86::BI__builtin_ia32_vcvtsd2sh_round_mask: |
4772 | 4.85k | case X86::BI__builtin_ia32_sqrtsd_round_mask: |
4773 | 5.44k | case X86::BI__builtin_ia32_sqrtss_round_mask: |
4774 | 5.45k | case X86::BI__builtin_ia32_sqrtsh_round_mask: |
4775 | 6.65k | case X86::BI__builtin_ia32_vfmaddsd3_mask: |
4776 | 7.84k | case X86::BI__builtin_ia32_vfmaddsd3_maskz: |
4777 | 8.43k | case X86::BI__builtin_ia32_vfmaddsd3_mask3: |
4778 | 9.63k | case X86::BI__builtin_ia32_vfmaddss3_mask: |
4779 | 10.8k | case X86::BI__builtin_ia32_vfmaddss3_maskz: |
4780 | 11.4k | case X86::BI__builtin_ia32_vfmaddss3_mask3: |
4781 | 11.4k | case X86::BI__builtin_ia32_vfmaddsh3_mask: |
4782 | 11.4k | case X86::BI__builtin_ia32_vfmaddsh3_maskz: |
4783 | 11.4k | case X86::BI__builtin_ia32_vfmaddsh3_mask3: |
4784 | 13.8k | case X86::BI__builtin_ia32_vfmaddpd512_mask: |
4785 | 15.0k | case X86::BI__builtin_ia32_vfmaddpd512_maskz: |
4786 | 15.6k | case X86::BI__builtin_ia32_vfmaddpd512_mask3: |
4787 | 16.2k | case X86::BI__builtin_ia32_vfmsubpd512_mask3: |
4788 | 18.5k | case X86::BI__builtin_ia32_vfmaddps512_mask: |
4789 | 19.7k | case X86::BI__builtin_ia32_vfmaddps512_maskz: |
4790 | 20.3k | case X86::BI__builtin_ia32_vfmaddps512_mask3: |
4791 | 20.9k | case X86::BI__builtin_ia32_vfmsubps512_mask3: |
4792 | 20.9k | case X86::BI__builtin_ia32_vfmaddph512_mask: |
4793 | 20.9k | case X86::BI__builtin_ia32_vfmaddph512_maskz: |
4794 | 21.0k | case X86::BI__builtin_ia32_vfmaddph512_mask3: |
4795 | 21.0k | case X86::BI__builtin_ia32_vfmsubph512_mask3: |
4796 | 22.1k | case X86::BI__builtin_ia32_vfmaddsubpd512_mask: |
4797 | 22.7k | case X86::BI__builtin_ia32_vfmaddsubpd512_maskz: |
4798 | 23.0k | case X86::BI__builtin_ia32_vfmaddsubpd512_mask3: |
4799 | 23.3k | case X86::BI__builtin_ia32_vfmsubaddpd512_mask3: |
4800 | 24.5k | case X86::BI__builtin_ia32_vfmaddsubps512_mask: |
4801 | 25.1k | case X86::BI__builtin_ia32_vfmaddsubps512_maskz: |
4802 | 25.4k | case X86::BI__builtin_ia32_vfmaddsubps512_mask3: |
4803 | 25.7k | case X86::BI__builtin_ia32_vfmsubaddps512_mask3: |
4804 | 25.7k | case X86::BI__builtin_ia32_vfmaddsubph512_mask: |
4805 | 25.7k | case X86::BI__builtin_ia32_vfmaddsubph512_maskz: |
4806 | 25.7k | case X86::BI__builtin_ia32_vfmaddsubph512_mask3: |
4807 | 25.7k | case X86::BI__builtin_ia32_vfmsubaddph512_mask3: |
4808 | 25.7k | case X86::BI__builtin_ia32_vfmaddcsh_mask: |
4809 | 25.7k | case X86::BI__builtin_ia32_vfmaddcsh_round_mask: |
4810 | 25.7k | case X86::BI__builtin_ia32_vfmaddcsh_round_mask3: |
4811 | 25.7k | case X86::BI__builtin_ia32_vfmaddcph512_mask: |
4812 | 25.7k | case X86::BI__builtin_ia32_vfmaddcph512_maskz: |
4813 | 25.8k | case X86::BI__builtin_ia32_vfmaddcph512_mask3: |
4814 | 25.8k | case X86::BI__builtin_ia32_vfcmaddcsh_mask: |
4815 | 25.8k | case X86::BI__builtin_ia32_vfcmaddcsh_round_mask: |
4816 | 25.8k | case X86::BI__builtin_ia32_vfcmaddcsh_round_mask3: |
4817 | 25.8k | case X86::BI__builtin_ia32_vfcmaddcph512_mask: |
4818 | 25.8k | case X86::BI__builtin_ia32_vfcmaddcph512_maskz: |
4819 | 25.8k | case X86::BI__builtin_ia32_vfcmaddcph512_mask3: |
4820 | 25.8k | case X86::BI__builtin_ia32_vfmulcsh_mask: |
4821 | 25.8k | case X86::BI__builtin_ia32_vfmulcph512_mask: |
4822 | 25.8k | case X86::BI__builtin_ia32_vfcmulcsh_mask: |
4823 | 25.8k | case X86::BI__builtin_ia32_vfcmulcph512_mask: |
4824 | 25.8k | ArgNum = 4; |
4825 | 25.8k | HasRC = true; |
4826 | 25.8k | break; |
4827 | 1.00M | } |
4828 | | |
4829 | 58.7k | llvm::APSInt Result; |
4830 | | |
4831 | | // We can't check the value of a dependent argument. |
4832 | 58.7k | Expr *Arg = TheCall->getArg(ArgNum); |
4833 | 58.7k | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
4834 | 0 | return false; |
4835 | | |
4836 | | // Check constant-ness first. |
4837 | 58.7k | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
4838 | 0 | return true; |
4839 | | |
4840 | | // Make sure rounding mode is either ROUND_CUR_DIRECTION or ROUND_NO_EXC bit |
4841 | | // is set. If the intrinsic has rounding control(bits 1:0), make sure its only |
4842 | | // combined with ROUND_NO_EXC. If the intrinsic does not have rounding |
4843 | | // control, allow ROUND_NO_EXC and ROUND_CUR_DIRECTION together. |
4844 | 58.7k | if (Result == 4/*ROUND_CUR_DIRECTION*/ || |
4845 | 58.7k | Result == 81.02k /*ROUND_NO_EXC*/ || |
4846 | 58.7k | (558 !HasRC558 && Result == 124 /*ROUND_CUR_DIRECTION|ROUND_NO_EXC*/) || |
4847 | 58.7k | (557 HasRC557 && Result.getZExtValue() >= 8554 && Result.getZExtValue() <= 11554 )) |
4848 | 58.7k | return false; |
4849 | | |
4850 | 3 | return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_rounding) |
4851 | 3 | << Arg->getSourceRange(); |
4852 | 58.7k | } |
4853 | | |
4854 | | // Check if the gather/scatter scale is legal. |
4855 | | bool Sema::CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, |
4856 | 1.00M | CallExpr *TheCall) { |
4857 | 1.00M | unsigned ArgNum = 0; |
4858 | 1.00M | switch (BuiltinID) { |
4859 | 1.00M | default: |
4860 | 1.00M | return false; |
4861 | 2 | case X86::BI__builtin_ia32_gatherpfdpd: |
4862 | 6 | case X86::BI__builtin_ia32_gatherpfdps: |
4863 | 8 | case X86::BI__builtin_ia32_gatherpfqpd: |
4864 | 10 | case X86::BI__builtin_ia32_gatherpfqps: |
4865 | 12 | case X86::BI__builtin_ia32_scatterpfdpd: |
4866 | 14 | case X86::BI__builtin_ia32_scatterpfdps: |
4867 | 16 | case X86::BI__builtin_ia32_scatterpfqpd: |
4868 | 18 | case X86::BI__builtin_ia32_scatterpfqps: |
4869 | 18 | ArgNum = 3; |
4870 | 18 | break; |
4871 | 8 | case X86::BI__builtin_ia32_gatherd_pd: |
4872 | 16 | case X86::BI__builtin_ia32_gatherd_pd256: |
4873 | 24 | case X86::BI__builtin_ia32_gatherq_pd: |
4874 | 32 | case X86::BI__builtin_ia32_gatherq_pd256: |
4875 | 40 | case X86::BI__builtin_ia32_gatherd_ps: |
4876 | 48 | case X86::BI__builtin_ia32_gatherd_ps256: |
4877 | 56 | case X86::BI__builtin_ia32_gatherq_ps: |
4878 | 64 | case X86::BI__builtin_ia32_gatherq_ps256: |
4879 | 72 | case X86::BI__builtin_ia32_gatherd_q: |
4880 | 80 | case X86::BI__builtin_ia32_gatherd_q256: |
4881 | 88 | case X86::BI__builtin_ia32_gatherq_q: |
4882 | 96 | case X86::BI__builtin_ia32_gatherq_q256: |
4883 | 105 | case X86::BI__builtin_ia32_gatherd_d: |
4884 | 113 | case X86::BI__builtin_ia32_gatherd_d256: |
4885 | 121 | case X86::BI__builtin_ia32_gatherq_d: |
4886 | 129 | case X86::BI__builtin_ia32_gatherq_d256: |
4887 | 130 | case X86::BI__builtin_ia32_gather3div2df: |
4888 | 131 | case X86::BI__builtin_ia32_gather3div2di: |
4889 | 132 | case X86::BI__builtin_ia32_gather3div4df: |
4890 | 133 | case X86::BI__builtin_ia32_gather3div4di: |
4891 | 134 | case X86::BI__builtin_ia32_gather3div4sf: |
4892 | 135 | case X86::BI__builtin_ia32_gather3div4si: |
4893 | 136 | case X86::BI__builtin_ia32_gather3div8sf: |
4894 | 137 | case X86::BI__builtin_ia32_gather3div8si: |
4895 | 138 | case X86::BI__builtin_ia32_gather3siv2df: |
4896 | 139 | case X86::BI__builtin_ia32_gather3siv2di: |
4897 | 140 | case X86::BI__builtin_ia32_gather3siv4df: |
4898 | 141 | case X86::BI__builtin_ia32_gather3siv4di: |
4899 | 142 | case X86::BI__builtin_ia32_gather3siv4sf: |
4900 | 143 | case X86::BI__builtin_ia32_gather3siv4si: |
4901 | 144 | case X86::BI__builtin_ia32_gather3siv8sf: |
4902 | 145 | case X86::BI__builtin_ia32_gather3siv8si: |
4903 | 153 | case X86::BI__builtin_ia32_gathersiv8df: |
4904 | 157 | case X86::BI__builtin_ia32_gathersiv16sf: |
4905 | 161 | case X86::BI__builtin_ia32_gatherdiv8df: |
4906 | 165 | case X86::BI__builtin_ia32_gatherdiv16sf: |
4907 | 173 | case X86::BI__builtin_ia32_gathersiv8di: |
4908 | 177 | case X86::BI__builtin_ia32_gathersiv16si: |
4909 | 181 | case X86::BI__builtin_ia32_gatherdiv8di: |
4910 | 185 | case X86::BI__builtin_ia32_gatherdiv16si: |
4911 | 187 | case X86::BI__builtin_ia32_scatterdiv2df: |
4912 | 189 | case X86::BI__builtin_ia32_scatterdiv2di: |
4913 | 191 | case X86::BI__builtin_ia32_scatterdiv4df: |
4914 | 193 | case X86::BI__builtin_ia32_scatterdiv4di: |
4915 | 195 | case X86::BI__builtin_ia32_scatterdiv4sf: |
4916 | 197 | case X86::BI__builtin_ia32_scatterdiv4si: |
4917 | 199 | case X86::BI__builtin_ia32_scatterdiv8sf: |
4918 | 201 | case X86::BI__builtin_ia32_scatterdiv8si: |
4919 | 203 | case X86::BI__builtin_ia32_scattersiv2df: |
4920 | 205 | case X86::BI__builtin_ia32_scattersiv2di: |
4921 | 207 | case X86::BI__builtin_ia32_scattersiv4df: |
4922 | 209 | case X86::BI__builtin_ia32_scattersiv4di: |
4923 | 211 | case X86::BI__builtin_ia32_scattersiv4sf: |
4924 | 213 | case X86::BI__builtin_ia32_scattersiv4si: |
4925 | 215 | case X86::BI__builtin_ia32_scattersiv8sf: |
4926 | 217 | case X86::BI__builtin_ia32_scattersiv8si: |
4927 | 225 | case X86::BI__builtin_ia32_scattersiv8df: |
4928 | 229 | case X86::BI__builtin_ia32_scattersiv16sf: |
4929 | 233 | case X86::BI__builtin_ia32_scatterdiv8df: |
4930 | 237 | case X86::BI__builtin_ia32_scatterdiv16sf: |
4931 | 245 | case X86::BI__builtin_ia32_scattersiv8di: |
4932 | 249 | case X86::BI__builtin_ia32_scattersiv16si: |
4933 | 253 | case X86::BI__builtin_ia32_scatterdiv8di: |
4934 | 257 | case X86::BI__builtin_ia32_scatterdiv16si: |
4935 | 257 | ArgNum = 4; |
4936 | 257 | break; |
4937 | 1.00M | } |
4938 | | |
4939 | 275 | llvm::APSInt Result; |
4940 | | |
4941 | | // We can't check the value of a dependent argument. |
4942 | 275 | Expr *Arg = TheCall->getArg(ArgNum); |
4943 | 275 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
4944 | 0 | return false; |
4945 | | |
4946 | | // Check constant-ness first. |
4947 | 275 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
4948 | 0 | return true; |
4949 | | |
4950 | 275 | if (Result == 1 || Result == 2266 || Result == 42 || Result == 82 ) |
4951 | 273 | return false; |
4952 | | |
4953 | 2 | return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_scale) |
4954 | 2 | << Arg->getSourceRange(); |
4955 | 275 | } |
4956 | | |
4957 | | enum { TileRegLow = 0, TileRegHigh = 7 }; |
4958 | | |
4959 | | bool Sema::CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, |
4960 | 20 | ArrayRef<int> ArgNums) { |
4961 | 41 | for (int ArgNum : ArgNums) { |
4962 | 41 | if (SemaBuiltinConstantArgRange(TheCall, ArgNum, TileRegLow, TileRegHigh)) |
4963 | 7 | return true; |
4964 | 41 | } |
4965 | 13 | return false; |
4966 | 20 | } |
4967 | | |
4968 | | bool Sema::CheckX86BuiltinTileDuplicate(CallExpr *TheCall, |
4969 | 9 | ArrayRef<int> ArgNums) { |
4970 | | // Because the max number of tile register is TileRegHigh + 1, so here we use |
4971 | | // each bit to represent the usage of them in bitset. |
4972 | 9 | std::bitset<TileRegHigh + 1> ArgValues; |
4973 | 26 | for (int ArgNum : ArgNums) { |
4974 | 26 | Expr *Arg = TheCall->getArg(ArgNum); |
4975 | 26 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
4976 | 0 | continue; |
4977 | | |
4978 | 26 | llvm::APSInt Result; |
4979 | 26 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
4980 | 0 | return true; |
4981 | 26 | int ArgExtValue = Result.getExtValue(); |
4982 | 26 | assert((ArgExtValue >= TileRegLow || ArgExtValue <= TileRegHigh) && |
4983 | 26 | "Incorrect tile register num."); |
4984 | 26 | if (ArgValues.test(ArgExtValue)) |
4985 | 4 | return Diag(TheCall->getBeginLoc(), |
4986 | 4 | diag::err_x86_builtin_tile_arg_duplicate) |
4987 | 4 | << TheCall->getArg(ArgNum)->getSourceRange(); |
4988 | 22 | ArgValues.set(ArgExtValue); |
4989 | 22 | } |
4990 | 5 | return false; |
4991 | 9 | } |
4992 | | |
4993 | | bool Sema::CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, |
4994 | 12 | ArrayRef<int> ArgNums) { |
|