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