1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
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/Stmt.h" |
34 | #include "clang/AST/TemplateBase.h" |
35 | #include "clang/AST/Type.h" |
36 | #include "clang/AST/TypeLoc.h" |
37 | #include "clang/AST/UnresolvedSet.h" |
38 | #include "clang/Basic/AddressSpaces.h" |
39 | #include "clang/Basic/CharInfo.h" |
40 | #include "clang/Basic/Diagnostic.h" |
41 | #include "clang/Basic/IdentifierTable.h" |
42 | #include "clang/Basic/LLVM.h" |
43 | #include "clang/Basic/LangOptions.h" |
44 | #include "clang/Basic/OpenCLOptions.h" |
45 | #include "clang/Basic/OperatorKinds.h" |
46 | #include "clang/Basic/PartialDiagnostic.h" |
47 | #include "clang/Basic/SourceLocation.h" |
48 | #include "clang/Basic/SourceManager.h" |
49 | #include "clang/Basic/Specifiers.h" |
50 | #include "clang/Basic/SyncScope.h" |
51 | #include "clang/Basic/TargetBuiltins.h" |
52 | #include "clang/Basic/TargetCXXABI.h" |
53 | #include "clang/Basic/TargetInfo.h" |
54 | #include "clang/Basic/TypeTraits.h" |
55 | #include "clang/Lex/Lexer.h" |
56 | #include "clang/Sema/Initialization.h" |
57 | #include "clang/Sema/Lookup.h" |
58 | #include "clang/Sema/Ownership.h" |
59 | #include "clang/Sema/Scope.h" |
60 | #include "clang/Sema/ScopeInfo.h" |
61 | #include "clang/Sema/Sema.h" |
62 | #include "clang/Sema/SemaInternal.h" |
63 | #include "llvm/ADT/APFloat.h" |
64 | #include "llvm/ADT/APInt.h" |
65 | #include "llvm/ADT/APSInt.h" |
66 | #include "llvm/ADT/ArrayRef.h" |
67 | #include "llvm/ADT/DenseMap.h" |
68 | #include "llvm/ADT/FoldingSet.h" |
69 | #include "llvm/ADT/None.h" |
70 | #include "llvm/ADT/Optional.h" |
71 | #include "llvm/ADT/STLExtras.h" |
72 | #include "llvm/ADT/SmallBitVector.h" |
73 | #include "llvm/ADT/SmallPtrSet.h" |
74 | #include "llvm/ADT/SmallString.h" |
75 | #include "llvm/ADT/SmallVector.h" |
76 | #include "llvm/ADT/StringRef.h" |
77 | #include "llvm/ADT/StringSwitch.h" |
78 | #include "llvm/ADT/Triple.h" |
79 | #include "llvm/Support/AtomicOrdering.h" |
80 | #include "llvm/Support/Casting.h" |
81 | #include "llvm/Support/Compiler.h" |
82 | #include "llvm/Support/ConvertUTF.h" |
83 | #include "llvm/Support/ErrorHandling.h" |
84 | #include "llvm/Support/Format.h" |
85 | #include "llvm/Support/Locale.h" |
86 | #include "llvm/Support/MathExtras.h" |
87 | #include "llvm/Support/raw_ostream.h" |
88 | #include <algorithm> |
89 | #include <cassert> |
90 | #include <cstddef> |
91 | #include <cstdint> |
92 | #include <functional> |
93 | #include <limits> |
94 | #include <string> |
95 | #include <tuple> |
96 | #include <utility> |
97 | |
98 | using namespace clang; |
99 | using namespace sema; |
100 | |
101 | SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL, |
102 | unsigned ByteNo) const { |
103 | return SL->getLocationOfByte(ByteNo, getSourceManager(), LangOpts, |
104 | Context.getTargetInfo()); |
105 | } |
106 | |
107 | |
108 | |
109 | static bool checkArgCount(Sema &S, CallExpr *call, unsigned desiredArgCount) { |
110 | unsigned argCount = call->getNumArgs(); |
111 | if (argCount == desiredArgCount) return false; |
112 | |
113 | if (argCount < desiredArgCount) |
114 | return S.Diag(call->getEndLoc(), diag::err_typecheck_call_too_few_args) |
115 | << 0 << desiredArgCount << argCount |
116 | << call->getSourceRange(); |
117 | |
118 | |
119 | SourceRange range(call->getArg(desiredArgCount)->getBeginLoc(), |
120 | call->getArg(argCount - 1)->getEndLoc()); |
121 | |
122 | return S.Diag(range.getBegin(), diag::err_typecheck_call_too_many_args) |
123 | << 0 << desiredArgCount << argCount |
124 | << call->getArg(1)->getSourceRange(); |
125 | } |
126 | |
127 | |
128 | |
129 | static bool SemaBuiltinAnnotation(Sema &S, CallExpr *TheCall) { |
130 | if (checkArgCount(S, TheCall, 2)) |
131 | return true; |
132 | |
133 | |
134 | Expr *ValArg = TheCall->getArg(0); |
135 | QualType Ty = ValArg->getType(); |
136 | if (!Ty->isIntegerType()) { |
137 | S.Diag(ValArg->getBeginLoc(), diag::err_builtin_annotation_first_arg) |
138 | << ValArg->getSourceRange(); |
139 | return true; |
140 | } |
141 | |
142 | |
143 | Expr *StrArg = TheCall->getArg(1)->IgnoreParenCasts(); |
144 | StringLiteral *Literal = dyn_cast<StringLiteral>(StrArg); |
145 | if (!Literal || !Literal->isAscii()) { |
146 | S.Diag(StrArg->getBeginLoc(), diag::err_builtin_annotation_second_arg) |
147 | << StrArg->getSourceRange(); |
148 | return true; |
149 | } |
150 | |
151 | TheCall->setType(Ty); |
152 | return false; |
153 | } |
154 | |
155 | static bool SemaBuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall) { |
156 | |
157 | if (TheCall->getNumArgs() < 1) { |
158 | S.Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) |
159 | << 0 << 1 << TheCall->getNumArgs() |
160 | << TheCall->getCallee()->getSourceRange(); |
161 | return true; |
162 | } |
163 | |
164 | |
165 | for (Expr *Arg : TheCall->arguments()) { |
166 | auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts()); |
167 | if (!Literal || !Literal->isWide()) { |
168 | S.Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str) |
169 | << Arg->getSourceRange(); |
170 | return true; |
171 | } |
172 | } |
173 | |
174 | return false; |
175 | } |
176 | |
177 | |
178 | |
179 | static bool SemaBuiltinAddressof(Sema &S, CallExpr *TheCall) { |
180 | if (checkArgCount(S, TheCall, 1)) |
181 | return true; |
182 | |
183 | ExprResult Arg(TheCall->getArg(0)); |
184 | QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getBeginLoc()); |
185 | if (ResultType.isNull()) |
186 | return true; |
187 | |
188 | TheCall->setArg(0, Arg.get()); |
189 | TheCall->setType(ResultType); |
190 | return false; |
191 | } |
192 | |
193 | static bool SemaBuiltinOverflow(Sema &S, CallExpr *TheCall) { |
194 | if (checkArgCount(S, TheCall, 3)) |
195 | return true; |
196 | |
197 | |
198 | for (unsigned I = 0; I < 2; ++I) { |
199 | ExprResult Arg = TheCall->getArg(I); |
200 | QualType Ty = Arg.get()->getType(); |
201 | if (!Ty->isIntegerType()) { |
202 | S.Diag(Arg.get()->getBeginLoc(), diag::err_overflow_builtin_must_be_int) |
203 | << Ty << Arg.get()->getSourceRange(); |
204 | return true; |
205 | } |
206 | InitializedEntity Entity = InitializedEntity::InitializeParameter( |
207 | S.getASTContext(), Ty, false); |
208 | Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg); |
209 | if (Arg.isInvalid()) |
210 | return true; |
211 | TheCall->setArg(I, Arg.get()); |
212 | } |
213 | |
214 | |
215 | |
216 | |
217 | { |
218 | ExprResult Arg = TheCall->getArg(2); |
219 | QualType Ty = Arg.get()->getType(); |
220 | const auto *PtrTy = Ty->getAs<PointerType>(); |
221 | if (!(PtrTy && PtrTy->getPointeeType()->isIntegerType() && |
222 | !PtrTy->getPointeeType().isConstQualified())) { |
223 | S.Diag(Arg.get()->getBeginLoc(), |
224 | diag::err_overflow_builtin_must_be_ptr_int) |
225 | << Ty << Arg.get()->getSourceRange(); |
226 | return true; |
227 | } |
228 | InitializedEntity Entity = InitializedEntity::InitializeParameter( |
229 | S.getASTContext(), Ty, false); |
230 | Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg); |
231 | if (Arg.isInvalid()) |
232 | return true; |
233 | TheCall->setArg(2, Arg.get()); |
234 | } |
235 | return false; |
236 | } |
237 | |
238 | static bool SemaBuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) { |
239 | if (checkArgCount(S, BuiltinCall, 2)) |
240 | return true; |
241 | |
242 | SourceLocation BuiltinLoc = BuiltinCall->getBeginLoc(); |
243 | Expr *Builtin = BuiltinCall->getCallee()->IgnoreImpCasts(); |
244 | Expr *Call = BuiltinCall->getArg(0); |
245 | Expr *Chain = BuiltinCall->getArg(1); |
246 | |
247 | if (Call->getStmtClass() != Stmt::CallExprClass) { |
248 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call) |
249 | << Call->getSourceRange(); |
250 | return true; |
251 | } |
252 | |
253 | auto CE = cast<CallExpr>(Call); |
254 | if (CE->getCallee()->getType()->isBlockPointerType()) { |
255 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call) |
256 | << Call->getSourceRange(); |
257 | return true; |
258 | } |
259 | |
260 | const Decl *TargetDecl = CE->getCalleeDecl(); |
261 | if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) |
262 | if (FD->getBuiltinID()) { |
263 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call) |
264 | << Call->getSourceRange(); |
265 | return true; |
266 | } |
267 | |
268 | if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) { |
269 | S.Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call) |
270 | << Call->getSourceRange(); |
271 | return true; |
272 | } |
273 | |
274 | ExprResult ChainResult = S.UsualUnaryConversions(Chain); |
275 | if (ChainResult.isInvalid()) |
276 | return true; |
277 | if (!ChainResult.get()->getType()->isPointerType()) { |
278 | S.Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer) |
279 | << Chain->getSourceRange(); |
280 | return true; |
281 | } |
282 | |
283 | QualType ReturnTy = CE->getCallReturnType(S.Context); |
284 | QualType ArgTys[2] = { ReturnTy, ChainResult.get()->getType() }; |
285 | QualType BuiltinTy = S.Context.getFunctionType( |
286 | ReturnTy, ArgTys, FunctionProtoType::ExtProtoInfo()); |
287 | QualType BuiltinPtrTy = S.Context.getPointerType(BuiltinTy); |
288 | |
289 | Builtin = |
290 | S.ImpCastExprToType(Builtin, BuiltinPtrTy, CK_BuiltinFnToFnPtr).get(); |
291 | |
292 | BuiltinCall->setType(CE->getType()); |
293 | BuiltinCall->setValueKind(CE->getValueKind()); |
294 | BuiltinCall->setObjectKind(CE->getObjectKind()); |
295 | BuiltinCall->setCallee(Builtin); |
296 | BuiltinCall->setArg(1, ChainResult.get()); |
297 | |
298 | return false; |
299 | } |
300 | |
301 | |
302 | |
303 | |
304 | void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, |
305 | CallExpr *TheCall) { |
306 | |
307 | |
308 | |
309 | |
310 | unsigned BuiltinID = FD->getBuiltinID(); |
311 | if (!BuiltinID) |
312 | return; |
313 | |
314 | unsigned DiagID = 0; |
315 | bool IsChkVariant = false; |
316 | unsigned SizeIndex, ObjectIndex; |
317 | switch (BuiltinID) { |
318 | default: |
319 | return; |
320 | case Builtin::BI__builtin___memcpy_chk: |
321 | case Builtin::BI__builtin___memmove_chk: |
322 | case Builtin::BI__builtin___memset_chk: |
323 | case Builtin::BI__builtin___strlcat_chk: |
324 | case Builtin::BI__builtin___strlcpy_chk: |
325 | case Builtin::BI__builtin___strncat_chk: |
326 | case Builtin::BI__builtin___strncpy_chk: |
327 | case Builtin::BI__builtin___stpncpy_chk: |
328 | case Builtin::BI__builtin___memccpy_chk: { |
329 | DiagID = diag::warn_builtin_chk_overflow; |
330 | IsChkVariant = true; |
331 | SizeIndex = TheCall->getNumArgs() - 2; |
332 | ObjectIndex = TheCall->getNumArgs() - 1; |
333 | break; |
334 | } |
335 | |
336 | case Builtin::BI__builtin___snprintf_chk: |
337 | case Builtin::BI__builtin___vsnprintf_chk: { |
338 | DiagID = diag::warn_builtin_chk_overflow; |
339 | IsChkVariant = true; |
340 | SizeIndex = 1; |
341 | ObjectIndex = 3; |
342 | break; |
343 | } |
344 | |
345 | case Builtin::BIstrncat: |
346 | case Builtin::BI__builtin_strncat: |
347 | case Builtin::BIstrncpy: |
348 | case Builtin::BI__builtin_strncpy: |
349 | case Builtin::BIstpncpy: |
350 | case Builtin::BI__builtin_stpncpy: { |
351 | |
352 | |
353 | |
354 | |
355 | |
356 | DiagID = diag::warn_fortify_source_size_mismatch; |
357 | SizeIndex = TheCall->getNumArgs() - 1; |
358 | ObjectIndex = 0; |
359 | break; |
360 | } |
361 | |
362 | case Builtin::BImemcpy: |
363 | case Builtin::BI__builtin_memcpy: |
364 | case Builtin::BImemmove: |
365 | case Builtin::BI__builtin_memmove: |
366 | case Builtin::BImemset: |
367 | case Builtin::BI__builtin_memset: { |
368 | DiagID = diag::warn_fortify_source_overflow; |
369 | SizeIndex = TheCall->getNumArgs() - 1; |
370 | ObjectIndex = 0; |
371 | break; |
372 | } |
373 | case Builtin::BIsnprintf: |
374 | case Builtin::BI__builtin_snprintf: |
375 | case Builtin::BIvsnprintf: |
376 | case Builtin::BI__builtin_vsnprintf: { |
377 | DiagID = diag::warn_fortify_source_size_mismatch; |
378 | SizeIndex = 1; |
379 | ObjectIndex = 0; |
380 | break; |
381 | } |
382 | } |
383 | |
384 | llvm::APSInt ObjectSize; |
385 | |
386 | |
387 | if (IsChkVariant) { |
388 | Expr::EvalResult Result; |
389 | Expr *SizeArg = TheCall->getArg(ObjectIndex); |
390 | if (!SizeArg->EvaluateAsInt(Result, getASTContext())) |
391 | return; |
392 | ObjectSize = Result.Val.getInt(); |
393 | |
394 | |
395 | } else { |
396 | |
397 | |
398 | |
399 | int BOSType = 0; |
400 | if (const auto *POS = |
401 | FD->getParamDecl(ObjectIndex)->getAttr<PassObjectSizeAttr>()) |
402 | BOSType = POS->getType(); |
403 | |
404 | Expr *ObjArg = TheCall->getArg(ObjectIndex); |
405 | uint64_t Result; |
406 | if (!ObjArg->tryEvaluateObjectSize(Result, getASTContext(), BOSType)) |
407 | return; |
408 | |
409 | const TargetInfo &TI = getASTContext().getTargetInfo(); |
410 | unsigned SizeTypeWidth = TI.getTypeWidth(TI.getSizeType()); |
411 | ObjectSize = llvm::APSInt::getUnsigned(Result).extOrTrunc(SizeTypeWidth); |
412 | } |
413 | |
414 | |
415 | Expr::EvalResult Result; |
416 | Expr *UsedSizeArg = TheCall->getArg(SizeIndex); |
417 | if (!UsedSizeArg->EvaluateAsInt(Result, getASTContext())) |
418 | return; |
419 | llvm::APSInt UsedSize = Result.Val.getInt(); |
420 | |
421 | if (UsedSize.ule(ObjectSize)) |
422 | return; |
423 | |
424 | StringRef FunctionName = getASTContext().BuiltinInfo.getName(BuiltinID); |
425 | |
426 | |
427 | if (IsChkVariant) { |
428 | FunctionName = FunctionName.drop_front(std::strlen("__builtin___")); |
429 | FunctionName = FunctionName.drop_back(std::strlen("_chk")); |
430 | } else if (FunctionName.startswith("__builtin_")) { |
431 | FunctionName = FunctionName.drop_front(std::strlen("__builtin_")); |
432 | } |
433 | |
434 | DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall, |
435 | PDiag(DiagID) |
436 | << FunctionName << ObjectSize.toString() |
437 | << UsedSize.toString()); |
438 | } |
439 | |
440 | static bool SemaBuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, |
441 | Scope::ScopeFlags NeededScopeFlags, |
442 | unsigned DiagID) { |
443 | |
444 | |
445 | |
446 | if (SemaRef.inTemplateInstantiation()) |
447 | return false; |
448 | |
449 | Scope *S = SemaRef.getCurScope(); |
450 | while (S && !S->isSEHExceptScope()) |
451 | S = S->getParent(); |
452 | if (!S || !(S->getFlags() & NeededScopeFlags)) { |
453 | auto *DRE = cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); |
454 | SemaRef.Diag(TheCall->getExprLoc(), DiagID) |
455 | << DRE->getDecl()->getIdentifier(); |
456 | return true; |
457 | } |
458 | |
459 | return false; |
460 | } |
461 | |
462 | static inline bool isBlockPointer(Expr *Arg) { |
463 | return Arg->getType()->isBlockPointerType(); |
464 | } |
465 | |
466 | |
467 | |
468 | static bool checkOpenCLBlockArgs(Sema &S, Expr *BlockArg) { |
469 | const BlockPointerType *BPT = |
470 | cast<BlockPointerType>(BlockArg->getType().getCanonicalType()); |
471 | ArrayRef<QualType> Params = |
472 | BPT->getPointeeType()->getAs<FunctionProtoType>()->getParamTypes(); |
473 | unsigned ArgCounter = 0; |
474 | bool IllegalParams = false; |
475 | |
476 | |
477 | for (ArrayRef<QualType>::iterator I = Params.begin(), E = Params.end(); |
478 | I != E; ++I, ++ArgCounter) { |
479 | if (!(*I)->isPointerType() || !(*I)->getPointeeType()->isVoidType() || |
480 | (*I)->getPointeeType().getQualifiers().getAddressSpace() != |
481 | LangAS::opencl_local) { |
482 | |
483 | |
484 | |
485 | SourceLocation ErrorLoc; |
486 | if (isa<BlockExpr>(BlockArg)) { |
487 | BlockDecl *BD = cast<BlockExpr>(BlockArg)->getBlockDecl(); |
488 | ErrorLoc = BD->getParamDecl(ArgCounter)->getBeginLoc(); |
489 | } else if (isa<DeclRefExpr>(BlockArg)) { |
490 | ErrorLoc = cast<DeclRefExpr>(BlockArg)->getBeginLoc(); |
491 | } |
492 | S.Diag(ErrorLoc, |
493 | diag::err_opencl_enqueue_kernel_blocks_non_local_void_args); |
494 | IllegalParams = true; |
495 | } |
496 | } |
497 | |
498 | return IllegalParams; |
499 | } |
500 | |
501 | static bool checkOpenCLSubgroupExt(Sema &S, CallExpr *Call) { |
502 | if (!S.getOpenCLOptions().isEnabled("cl_khr_subgroups")) { |
503 | S.Diag(Call->getBeginLoc(), diag::err_opencl_requires_extension) |
504 | << 1 << Call->getDirectCallee() << "cl_khr_subgroups"; |
505 | return true; |
506 | } |
507 | return false; |
508 | } |
509 | |
510 | static bool SemaOpenCLBuiltinNDRangeAndBlock(Sema &S, CallExpr *TheCall) { |
511 | if (checkArgCount(S, TheCall, 2)) |
512 | return true; |
513 | |
514 | if (checkOpenCLSubgroupExt(S, TheCall)) |
515 | return true; |
516 | |
517 | |
518 | Expr *NDRangeArg = TheCall->getArg(0); |
519 | if (NDRangeArg->getType().getUnqualifiedType().getAsString() != "ndrange_t") { |
520 | S.Diag(NDRangeArg->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
521 | << TheCall->getDirectCallee() << "'ndrange_t'"; |
522 | return true; |
523 | } |
524 | |
525 | Expr *BlockArg = TheCall->getArg(1); |
526 | if (!isBlockPointer(BlockArg)) { |
527 | S.Diag(BlockArg->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
528 | << TheCall->getDirectCallee() << "block"; |
529 | return true; |
530 | } |
531 | return checkOpenCLBlockArgs(S, BlockArg); |
532 | } |
533 | |
534 | |
535 | |
536 | |
537 | static bool SemaOpenCLBuiltinKernelWorkGroupSize(Sema &S, CallExpr *TheCall) { |
538 | if (checkArgCount(S, TheCall, 1)) |
539 | return true; |
540 | |
541 | Expr *BlockArg = TheCall->getArg(0); |
542 | if (!isBlockPointer(BlockArg)) { |
543 | S.Diag(BlockArg->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
544 | << TheCall->getDirectCallee() << "block"; |
545 | return true; |
546 | } |
547 | return checkOpenCLBlockArgs(S, BlockArg); |
548 | } |
549 | |
550 | |
551 | static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, |
552 | const QualType &IntType); |
553 | |
554 | static bool checkOpenCLEnqueueLocalSizeArgs(Sema &S, CallExpr *TheCall, |
555 | unsigned Start, unsigned End) { |
556 | bool IllegalParams = false; |
557 | for (unsigned I = Start; I <= End; ++I) |
558 | IllegalParams |= checkOpenCLEnqueueIntType(S, TheCall->getArg(I), |
559 | S.Context.getSizeType()); |
560 | return IllegalParams; |
561 | } |
562 | |
563 | |
564 | |
565 | static bool checkOpenCLEnqueueVariadicArgs(Sema &S, CallExpr *TheCall, |
566 | Expr *BlockArg, |
567 | unsigned NumNonVarArgs) { |
568 | const BlockPointerType *BPT = |
569 | cast<BlockPointerType>(BlockArg->getType().getCanonicalType()); |
570 | unsigned NumBlockParams = |
571 | BPT->getPointeeType()->getAs<FunctionProtoType>()->getNumParams(); |
572 | unsigned TotalNumArgs = TheCall->getNumArgs(); |
573 | |
574 | |
575 | |
576 | if (TotalNumArgs != NumBlockParams + NumNonVarArgs) { |
577 | S.Diag(TheCall->getBeginLoc(), |
578 | diag::err_opencl_enqueue_kernel_local_size_args); |
579 | return true; |
580 | } |
581 | |
582 | |
583 | return checkOpenCLEnqueueLocalSizeArgs(S, TheCall, NumNonVarArgs, |
584 | TotalNumArgs - 1); |
585 | } |
586 | |
587 | |
588 | |
589 | |
590 | |
591 | |
592 | |
593 | |
594 | |
595 | |
596 | |
597 | |
598 | |
599 | |
600 | |
601 | |
602 | |
603 | |
604 | |
605 | |
606 | |
607 | |
608 | |
609 | |
610 | |
611 | |
612 | |
613 | static bool SemaOpenCLBuiltinEnqueueKernel(Sema &S, CallExpr *TheCall) { |
614 | unsigned NumArgs = TheCall->getNumArgs(); |
615 | |
616 | if (NumArgs < 4) { |
617 | S.Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_few_args); |
618 | return true; |
619 | } |
620 | |
621 | Expr *Arg0 = TheCall->getArg(0); |
622 | Expr *Arg1 = TheCall->getArg(1); |
623 | Expr *Arg2 = TheCall->getArg(2); |
624 | Expr *Arg3 = TheCall->getArg(3); |
625 | |
626 | |
627 | if (!Arg0->getType()->isQueueT()) { |
628 | S.Diag(TheCall->getArg(0)->getBeginLoc(), |
629 | diag::err_opencl_builtin_expected_type) |
630 | << TheCall->getDirectCallee() << S.Context.OCLQueueTy; |
631 | return true; |
632 | } |
633 | |
634 | |
635 | if (!Arg1->getType()->isIntegerType()) { |
636 | S.Diag(TheCall->getArg(1)->getBeginLoc(), |
637 | diag::err_opencl_builtin_expected_type) |
638 | << TheCall->getDirectCallee() << "'kernel_enqueue_flags_t' (i.e. uint)"; |
639 | return true; |
640 | } |
641 | |
642 | |
643 | if (Arg2->getType().getUnqualifiedType().getAsString() != "ndrange_t") { |
644 | S.Diag(TheCall->getArg(2)->getBeginLoc(), |
645 | diag::err_opencl_builtin_expected_type) |
646 | << TheCall->getDirectCallee() << "'ndrange_t'"; |
647 | return true; |
648 | } |
649 | |
650 | |
651 | |
652 | if (NumArgs == 4) { |
653 | |
654 | if (!isBlockPointer(Arg3)) { |
655 | S.Diag(Arg3->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
656 | << TheCall->getDirectCallee() << "block"; |
657 | return true; |
658 | } |
659 | |
660 | const BlockPointerType *BPT = |
661 | cast<BlockPointerType>(Arg3->getType().getCanonicalType()); |
662 | if (BPT->getPointeeType()->getAs<FunctionProtoType>()->getNumParams() > 0) { |
663 | S.Diag(Arg3->getBeginLoc(), |
664 | diag::err_opencl_enqueue_kernel_blocks_no_args); |
665 | return true; |
666 | } |
667 | return false; |
668 | } |
669 | |
670 | if (isBlockPointer(Arg3)) |
671 | return (checkOpenCLBlockArgs(S, Arg3) || |
672 | checkOpenCLEnqueueVariadicArgs(S, TheCall, Arg3, 4)); |
673 | |
674 | if (NumArgs >= 7) { |
675 | |
676 | Expr *Arg6 = TheCall->getArg(6); |
677 | if (!isBlockPointer(Arg6)) { |
678 | S.Diag(Arg6->getBeginLoc(), diag::err_opencl_builtin_expected_type) |
679 | << TheCall->getDirectCallee() << "block"; |
680 | return true; |
681 | } |
682 | if (checkOpenCLBlockArgs(S, Arg6)) |
683 | return true; |
684 | |
685 | |
686 | if (!Arg3->getType()->isIntegerType()) { |
687 | S.Diag(TheCall->getArg(3)->getBeginLoc(), |
688 | diag::err_opencl_builtin_expected_type) |
689 | << TheCall->getDirectCallee() << "integer"; |
690 | return true; |
691 | } |
692 | |
693 | Expr *Arg4 = TheCall->getArg(4); |
694 | Expr *Arg5 = TheCall->getArg(5); |
695 | |
696 | |
697 | if (!Arg4->isNullPointerConstant(S.Context, |
698 | Expr::NPC_ValueDependentIsNotNull) && |
699 | !Arg4->getType()->getPointeeOrArrayElementType()->isClkEventT()) { |
700 | S.Diag(TheCall->getArg(4)->getBeginLoc(), |
701 | diag::err_opencl_builtin_expected_type) |
702 | << TheCall->getDirectCallee() |
703 | << S.Context.getPointerType(S.Context.OCLClkEventTy); |
704 | return true; |
705 | } |
706 | |
707 | |
708 | if (!Arg5->isNullPointerConstant(S.Context, |
709 | Expr::NPC_ValueDependentIsNotNull) && |
710 | !(Arg5->getType()->isPointerType() && |
711 | Arg5->getType()->getPointeeType()->isClkEventT())) { |
712 | S.Diag(TheCall->getArg(5)->getBeginLoc(), |
713 | diag::err_opencl_builtin_expected_type) |
714 | << TheCall->getDirectCallee() |
715 | << S.Context.getPointerType(S.Context.OCLClkEventTy); |
716 | return true; |
717 | } |
718 | |
719 | if (NumArgs == 7) |
720 | return false; |
721 | |
722 | return checkOpenCLEnqueueVariadicArgs(S, TheCall, Arg6, 7); |
723 | } |
724 | |
725 | |
726 | S.Diag(TheCall->getBeginLoc(), |
727 | diag::err_opencl_enqueue_kernel_incorrect_args); |
728 | return true; |
729 | } |
730 | |
731 | |
732 | static OpenCLAccessAttr *getOpenCLArgAccess(const Decl *D) { |
733 | return D->getAttr<OpenCLAccessAttr>(); |
734 | } |
735 | |
736 | |
737 | static bool checkOpenCLPipeArg(Sema &S, CallExpr *Call) { |
738 | const Expr *Arg0 = Call->getArg(0); |
739 | |
740 | if (!Arg0->getType()->isPipeType()) { |
741 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg) |
742 | << Call->getDirectCallee() << Arg0->getSourceRange(); |
743 | return true; |
744 | } |
745 | OpenCLAccessAttr *AccessQual = |
746 | getOpenCLArgAccess(cast<DeclRefExpr>(Arg0)->getDecl()); |
747 | |
748 | |
749 | |
750 | |
751 | switch (Call->getDirectCallee()->getBuiltinID()) { |
752 | case Builtin::BIread_pipe: |
753 | case Builtin::BIreserve_read_pipe: |
754 | case Builtin::BIcommit_read_pipe: |
755 | case Builtin::BIwork_group_reserve_read_pipe: |
756 | case Builtin::BIsub_group_reserve_read_pipe: |
757 | case Builtin::BIwork_group_commit_read_pipe: |
758 | case Builtin::BIsub_group_commit_read_pipe: |
759 | if (!(!AccessQual || AccessQual->isReadOnly())) { |
760 | S.Diag(Arg0->getBeginLoc(), |
761 | diag::err_opencl_builtin_pipe_invalid_access_modifier) |
762 | << "read_only" << Arg0->getSourceRange(); |
763 | return true; |
764 | } |
765 | break; |
766 | case Builtin::BIwrite_pipe: |
767 | case Builtin::BIreserve_write_pipe: |
768 | case Builtin::BIcommit_write_pipe: |
769 | case Builtin::BIwork_group_reserve_write_pipe: |
770 | case Builtin::BIsub_group_reserve_write_pipe: |
771 | case Builtin::BIwork_group_commit_write_pipe: |
772 | case Builtin::BIsub_group_commit_write_pipe: |
773 | if (!(AccessQual && AccessQual->isWriteOnly())) { |
774 | S.Diag(Arg0->getBeginLoc(), |
775 | diag::err_opencl_builtin_pipe_invalid_access_modifier) |
776 | << "write_only" << Arg0->getSourceRange(); |
777 | return true; |
778 | } |
779 | break; |
780 | default: |
781 | break; |
782 | } |
783 | return false; |
784 | } |
785 | |
786 | |
787 | static bool checkOpenCLPipePacketType(Sema &S, CallExpr *Call, unsigned Idx) { |
788 | const Expr *Arg0 = Call->getArg(0); |
789 | const Expr *ArgIdx = Call->getArg(Idx); |
790 | const PipeType *PipeTy = cast<PipeType>(Arg0->getType()); |
791 | const QualType EltTy = PipeTy->getElementType(); |
792 | const PointerType *ArgTy = ArgIdx->getType()->getAs<PointerType>(); |
793 | |
794 | |
795 | if (!ArgTy || |
796 | !S.Context.hasSameType( |
797 | EltTy, ArgTy->getPointeeType()->getCanonicalTypeInternal())) { |
798 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
799 | << Call->getDirectCallee() << S.Context.getPointerType(EltTy) |
800 | << ArgIdx->getType() << ArgIdx->getSourceRange(); |
801 | return true; |
802 | } |
803 | return false; |
804 | } |
805 | |
806 | |
807 | |
808 | |
809 | |
810 | static bool SemaBuiltinRWPipe(Sema &S, CallExpr *Call) { |
811 | |
812 | |
813 | switch (Call->getNumArgs()) { |
814 | case 2: |
815 | if (checkOpenCLPipeArg(S, Call)) |
816 | return true; |
817 | |
818 | |
819 | |
820 | if (checkOpenCLPipePacketType(S, Call, 1)) |
821 | return true; |
822 | break; |
823 | |
824 | case 4: { |
825 | if (checkOpenCLPipeArg(S, Call)) |
826 | return true; |
827 | |
828 | |
829 | |
830 | if (!Call->getArg(1)->getType()->isReserveIDT()) { |
831 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
832 | << Call->getDirectCallee() << S.Context.OCLReserveIDTy |
833 | << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange(); |
834 | return true; |
835 | } |
836 | |
837 | |
838 | const Expr *Arg2 = Call->getArg(2); |
839 | if (!Arg2->getType()->isIntegerType() && |
840 | !Arg2->getType()->isUnsignedIntegerType()) { |
841 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
842 | << Call->getDirectCallee() << S.Context.UnsignedIntTy |
843 | << Arg2->getType() << Arg2->getSourceRange(); |
844 | return true; |
845 | } |
846 | |
847 | |
848 | if (checkOpenCLPipePacketType(S, Call, 3)) |
849 | return true; |
850 | } break; |
851 | default: |
852 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_arg_num) |
853 | << Call->getDirectCallee() << Call->getSourceRange(); |
854 | return true; |
855 | } |
856 | |
857 | return false; |
858 | } |
859 | |
860 | |
861 | |
862 | |
863 | |
864 | |
865 | static bool SemaBuiltinReserveRWPipe(Sema &S, CallExpr *Call) { |
866 | if (checkArgCount(S, Call, 2)) |
867 | return true; |
868 | |
869 | if (checkOpenCLPipeArg(S, Call)) |
870 | return true; |
871 | |
872 | |
873 | if (!Call->getArg(1)->getType()->isIntegerType() && |
874 | !Call->getArg(1)->getType()->isUnsignedIntegerType()) { |
875 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
876 | << Call->getDirectCallee() << S.Context.UnsignedIntTy |
877 | << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange(); |
878 | return true; |
879 | } |
880 | |
881 | |
882 | |
883 | |
884 | Call->setType(S.Context.OCLReserveIDTy); |
885 | |
886 | return false; |
887 | } |
888 | |
889 | |
890 | |
891 | |
892 | |
893 | |
894 | static bool SemaBuiltinCommitRWPipe(Sema &S, CallExpr *Call) { |
895 | if (checkArgCount(S, Call, 2)) |
896 | return true; |
897 | |
898 | if (checkOpenCLPipeArg(S, Call)) |
899 | return true; |
900 | |
901 | |
902 | if (!Call->getArg(1)->getType()->isReserveIDT()) { |
903 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_invalid_arg) |
904 | << Call->getDirectCallee() << S.Context.OCLReserveIDTy |
905 | << Call->getArg(1)->getType() << Call->getArg(1)->getSourceRange(); |
906 | return true; |
907 | } |
908 | |
909 | return false; |
910 | } |
911 | |
912 | |
913 | |
914 | |
915 | |
916 | |
917 | static bool SemaBuiltinPipePackets(Sema &S, CallExpr *Call) { |
918 | if (checkArgCount(S, Call, 1)) |
919 | return true; |
920 | |
921 | if (!Call->getArg(0)->getType()->isPipeType()) { |
922 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_pipe_first_arg) |
923 | << Call->getDirectCallee() << Call->getArg(0)->getSourceRange(); |
924 | return true; |
925 | } |
926 | |
927 | return false; |
928 | } |
929 | |
930 | |
931 | |
932 | |
933 | |
934 | |
935 | |
936 | static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID, |
937 | CallExpr *Call) { |
938 | if (Call->getNumArgs() != 1) { |
939 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_to_addr_arg_num) |
940 | << Call->getDirectCallee() << Call->getSourceRange(); |
941 | return true; |
942 | } |
943 | |
944 | auto RT = Call->getArg(0)->getType(); |
945 | if (!RT->isPointerType() || RT->getPointeeType() |
946 | .getAddressSpace() == LangAS::opencl_constant) { |
947 | S.Diag(Call->getBeginLoc(), diag::err_opencl_builtin_to_addr_invalid_arg) |
948 | << Call->getArg(0) << Call->getDirectCallee() << Call->getSourceRange(); |
949 | return true; |
950 | } |
951 | |
952 | if (RT->getPointeeType().getAddressSpace() != LangAS::opencl_generic) { |
953 | S.Diag(Call->getArg(0)->getBeginLoc(), |
954 | diag::warn_opencl_generic_address_space_arg) |
955 | << Call->getDirectCallee()->getNameInfo().getAsString() |
956 | << Call->getArg(0)->getSourceRange(); |
957 | } |
958 | |
959 | RT = RT->getPointeeType(); |
960 | auto Qual = RT.getQualifiers(); |
961 | switch (BuiltinID) { |
962 | case Builtin::BIto_global: |
963 | Qual.setAddressSpace(LangAS::opencl_global); |
964 | break; |
965 | case Builtin::BIto_local: |
966 | Qual.setAddressSpace(LangAS::opencl_local); |
967 | break; |
968 | case Builtin::BIto_private: |
969 | Qual.setAddressSpace(LangAS::opencl_private); |
970 | break; |
971 | default: |
972 | llvm_unreachable("Invalid builtin function"); |
973 | } |
974 | Call->setType(S.Context.getPointerType(S.Context.getQualifiedType( |
975 | RT.getUnqualifiedType(), Qual))); |
976 | |
977 | return false; |
978 | } |
979 | |
980 | static ExprResult SemaBuiltinLaunder(Sema &S, CallExpr *TheCall) { |
981 | if (checkArgCount(S, TheCall, 1)) |
982 | return ExprError(); |
983 | |
984 | |
985 | |
986 | |
987 | |
988 | |
989 | QualType ParamTy = [&]() { |
990 | QualType ArgTy = TheCall->getArg(0)->getType(); |
991 | if (const ArrayType *Ty = ArgTy->getAsArrayTypeUnsafe()) |
992 | return S.Context.getPointerType(Ty->getElementType()); |
993 | if (ArgTy->isFunctionType()) { |
994 | return S.Context.getPointerType(ArgTy); |
995 | } |
996 | return ArgTy; |
997 | }(); |
998 | |
999 | TheCall->setType(ParamTy); |
1000 | |
1001 | auto DiagSelect = [&]() -> llvm::Optional<unsigned> { |
1002 | if (!ParamTy->isPointerType()) |
1003 | return 0; |
1004 | if (ParamTy->isFunctionPointerType()) |
1005 | return 1; |
1006 | if (ParamTy->isVoidPointerType()) |
1007 | return 2; |
1008 | return llvm::Optional<unsigned>{}; |
1009 | }(); |
1010 | if (DiagSelect.hasValue()) { |
1011 | S.Diag(TheCall->getBeginLoc(), diag::err_builtin_launder_invalid_arg) |
1012 | << DiagSelect.getValue() << TheCall->getSourceRange(); |
1013 | return ExprError(); |
1014 | } |
1015 | |
1016 | |
1017 | |
1018 | |
1019 | |
1020 | |
1021 | |
1022 | if (S.RequireCompleteType(TheCall->getBeginLoc(), ParamTy->getPointeeType(), |
1023 | diag::err_incomplete_type)) |
1024 | return ExprError(); |
1025 | |
1026 | (0) . __assert_fail ("ParamTy->getPointeeType()->isObjectType() && \"Unhandled non-object pointer case\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1027, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ParamTy->getPointeeType()->isObjectType() && |
1027 | (0) . __assert_fail ("ParamTy->getPointeeType()->isObjectType() && \"Unhandled non-object pointer case\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1027, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Unhandled non-object pointer case"); |
1028 | |
1029 | InitializedEntity Entity = |
1030 | InitializedEntity::InitializeParameter(S.Context, ParamTy, false); |
1031 | ExprResult Arg = |
1032 | S.PerformCopyInitialization(Entity, SourceLocation(), TheCall->getArg(0)); |
1033 | if (Arg.isInvalid()) |
1034 | return ExprError(); |
1035 | TheCall->setArg(0, Arg.get()); |
1036 | |
1037 | return TheCall; |
1038 | } |
1039 | |
1040 | |
1041 | |
1042 | static bool |
1043 | CheckBuiltinTargetSupport(Sema &S, unsigned BuiltinID, CallExpr *TheCall, |
1044 | ArrayRef<llvm::Triple::ArchType> SupportedArchs) { |
1045 | llvm::Triple::ArchType CurArch = |
1046 | S.getASTContext().getTargetInfo().getTriple().getArch(); |
1047 | if (llvm::is_contained(SupportedArchs, CurArch)) |
1048 | return false; |
1049 | S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) |
1050 | << TheCall->getSourceRange(); |
1051 | return true; |
1052 | } |
1053 | |
1054 | ExprResult |
1055 | Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, |
1056 | CallExpr *TheCall) { |
1057 | ExprResult TheCallResult(TheCall); |
1058 | |
1059 | |
1060 | unsigned ICEArguments = 0; |
1061 | ASTContext::GetBuiltinTypeError Error; |
1062 | Context.GetBuiltinType(BuiltinID, Error, &ICEArguments); |
1063 | if (Error != ASTContext::GE_None) |
1064 | ICEArguments = 0; |
1065 | |
1066 | |
1067 | for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) { |
1068 | |
1069 | if ((ICEArguments & (1 << ArgNo)) == 0) continue; |
1070 | |
1071 | llvm::APSInt Result; |
1072 | if (SemaBuiltinConstantArg(TheCall, ArgNo, Result)) |
1073 | return true; |
1074 | ICEArguments &= ~(1 << ArgNo); |
1075 | } |
1076 | |
1077 | switch (BuiltinID) { |
1078 | case Builtin::BI__builtin___CFStringMakeConstantString: |
1079 | (0) . __assert_fail ("TheCall->getNumArgs() == 1 && \"Wrong # arguments to builtin CFStringMakeConstantString\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1080, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(TheCall->getNumArgs() == 1 && |
1080 | (0) . __assert_fail ("TheCall->getNumArgs() == 1 && \"Wrong # arguments to builtin CFStringMakeConstantString\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1080, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Wrong # arguments to builtin CFStringMakeConstantString"); |
1081 | if (CheckObjCString(TheCall->getArg(0))) |
1082 | return ExprError(); |
1083 | break; |
1084 | case Builtin::BI__builtin_ms_va_start: |
1085 | case Builtin::BI__builtin_stdarg_start: |
1086 | case Builtin::BI__builtin_va_start: |
1087 | if (SemaBuiltinVAStart(BuiltinID, TheCall)) |
1088 | return ExprError(); |
1089 | break; |
1090 | case Builtin::BI__va_start: { |
1091 | switch (Context.getTargetInfo().getTriple().getArch()) { |
1092 | case llvm::Triple::aarch64: |
1093 | case llvm::Triple::arm: |
1094 | case llvm::Triple::thumb: |
1095 | if (SemaBuiltinVAStartARMMicrosoft(TheCall)) |
1096 | return ExprError(); |
1097 | break; |
1098 | default: |
1099 | if (SemaBuiltinVAStart(BuiltinID, TheCall)) |
1100 | return ExprError(); |
1101 | break; |
1102 | } |
1103 | break; |
1104 | } |
1105 | |
1106 | |
1107 | case Builtin::BI_interlockedbittestandset_acq: |
1108 | case Builtin::BI_interlockedbittestandset_rel: |
1109 | case Builtin::BI_interlockedbittestandset_nf: |
1110 | case Builtin::BI_interlockedbittestandreset_acq: |
1111 | case Builtin::BI_interlockedbittestandreset_rel: |
1112 | case Builtin::BI_interlockedbittestandreset_nf: |
1113 | if (CheckBuiltinTargetSupport( |
1114 | *this, BuiltinID, TheCall, |
1115 | {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64})) |
1116 | return ExprError(); |
1117 | break; |
1118 | |
1119 | |
1120 | case Builtin::BI_bittest64: |
1121 | case Builtin::BI_bittestandcomplement64: |
1122 | case Builtin::BI_bittestandreset64: |
1123 | case Builtin::BI_bittestandset64: |
1124 | case Builtin::BI_interlockedbittestandreset64: |
1125 | case Builtin::BI_interlockedbittestandset64: |
1126 | if (CheckBuiltinTargetSupport(*this, BuiltinID, TheCall, |
1127 | {llvm::Triple::x86_64, llvm::Triple::arm, |
1128 | llvm::Triple::thumb, llvm::Triple::aarch64})) |
1129 | return ExprError(); |
1130 | break; |
1131 | |
1132 | case Builtin::BI__builtin_isgreater: |
1133 | case Builtin::BI__builtin_isgreaterequal: |
1134 | case Builtin::BI__builtin_isless: |
1135 | case Builtin::BI__builtin_islessequal: |
1136 | case Builtin::BI__builtin_islessgreater: |
1137 | case Builtin::BI__builtin_isunordered: |
1138 | if (SemaBuiltinUnorderedCompare(TheCall)) |
1139 | return ExprError(); |
1140 | break; |
1141 | case Builtin::BI__builtin_fpclassify: |
1142 | if (SemaBuiltinFPClassification(TheCall, 6)) |
1143 | return ExprError(); |
1144 | break; |
1145 | case Builtin::BI__builtin_isfinite: |
1146 | case Builtin::BI__builtin_isinf: |
1147 | case Builtin::BI__builtin_isinf_sign: |
1148 | case Builtin::BI__builtin_isnan: |
1149 | case Builtin::BI__builtin_isnormal: |
1150 | case Builtin::BI__builtin_signbit: |
1151 | case Builtin::BI__builtin_signbitf: |
1152 | case Builtin::BI__builtin_signbitl: |
1153 | if (SemaBuiltinFPClassification(TheCall, 1)) |
1154 | return ExprError(); |
1155 | break; |
1156 | case Builtin::BI__builtin_shufflevector: |
1157 | return SemaBuiltinShuffleVector(TheCall); |
1158 | |
1159 | |
1160 | case Builtin::BI__builtin_prefetch: |
1161 | if (SemaBuiltinPrefetch(TheCall)) |
1162 | return ExprError(); |
1163 | break; |
1164 | case Builtin::BI__builtin_alloca_with_align: |
1165 | if (SemaBuiltinAllocaWithAlign(TheCall)) |
1166 | return ExprError(); |
1167 | break; |
1168 | case Builtin::BI__assume: |
1169 | case Builtin::BI__builtin_assume: |
1170 | if (SemaBuiltinAssume(TheCall)) |
1171 | return ExprError(); |
1172 | break; |
1173 | case Builtin::BI__builtin_assume_aligned: |
1174 | if (SemaBuiltinAssumeAligned(TheCall)) |
1175 | return ExprError(); |
1176 | break; |
1177 | case Builtin::BI__builtin_dynamic_object_size: |
1178 | case Builtin::BI__builtin_object_size: |
1179 | if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3)) |
1180 | return ExprError(); |
1181 | break; |
1182 | case Builtin::BI__builtin_longjmp: |
1183 | if (SemaBuiltinLongjmp(TheCall)) |
1184 | return ExprError(); |
1185 | break; |
1186 | case Builtin::BI__builtin_setjmp: |
1187 | if (SemaBuiltinSetjmp(TheCall)) |
1188 | return ExprError(); |
1189 | break; |
1190 | case Builtin::BI_setjmp: |
1191 | case Builtin::BI_setjmpex: |
1192 | if (checkArgCount(*this, TheCall, 1)) |
1193 | return true; |
1194 | break; |
1195 | case Builtin::BI__builtin_classify_type: |
1196 | if (checkArgCount(*this, TheCall, 1)) return true; |
1197 | TheCall->setType(Context.IntTy); |
1198 | break; |
1199 | case Builtin::BI__builtin_constant_p: |
1200 | if (checkArgCount(*this, TheCall, 1)) return true; |
1201 | TheCall->setType(Context.IntTy); |
1202 | break; |
1203 | case Builtin::BI__builtin_launder: |
1204 | return SemaBuiltinLaunder(*this, TheCall); |
1205 | case Builtin::BI__sync_fetch_and_add: |
1206 | case Builtin::BI__sync_fetch_and_add_1: |
1207 | case Builtin::BI__sync_fetch_and_add_2: |
1208 | case Builtin::BI__sync_fetch_and_add_4: |
1209 | case Builtin::BI__sync_fetch_and_add_8: |
1210 | case Builtin::BI__sync_fetch_and_add_16: |
1211 | case Builtin::BI__sync_fetch_and_sub: |
1212 | case Builtin::BI__sync_fetch_and_sub_1: |
1213 | case Builtin::BI__sync_fetch_and_sub_2: |
1214 | case Builtin::BI__sync_fetch_and_sub_4: |
1215 | case Builtin::BI__sync_fetch_and_sub_8: |
1216 | case Builtin::BI__sync_fetch_and_sub_16: |
1217 | case Builtin::BI__sync_fetch_and_or: |
1218 | case Builtin::BI__sync_fetch_and_or_1: |
1219 | case Builtin::BI__sync_fetch_and_or_2: |
1220 | case Builtin::BI__sync_fetch_and_or_4: |
1221 | case Builtin::BI__sync_fetch_and_or_8: |
1222 | case Builtin::BI__sync_fetch_and_or_16: |
1223 | case Builtin::BI__sync_fetch_and_and: |
1224 | case Builtin::BI__sync_fetch_and_and_1: |
1225 | case Builtin::BI__sync_fetch_and_and_2: |
1226 | case Builtin::BI__sync_fetch_and_and_4: |
1227 | case Builtin::BI__sync_fetch_and_and_8: |
1228 | case Builtin::BI__sync_fetch_and_and_16: |
1229 | case Builtin::BI__sync_fetch_and_xor: |
1230 | case Builtin::BI__sync_fetch_and_xor_1: |
1231 | case Builtin::BI__sync_fetch_and_xor_2: |
1232 | case Builtin::BI__sync_fetch_and_xor_4: |
1233 | case Builtin::BI__sync_fetch_and_xor_8: |
1234 | case Builtin::BI__sync_fetch_and_xor_16: |
1235 | case Builtin::BI__sync_fetch_and_nand: |
1236 | case Builtin::BI__sync_fetch_and_nand_1: |
1237 | case Builtin::BI__sync_fetch_and_nand_2: |
1238 | case Builtin::BI__sync_fetch_and_nand_4: |
1239 | case Builtin::BI__sync_fetch_and_nand_8: |
1240 | case Builtin::BI__sync_fetch_and_nand_16: |
1241 | case Builtin::BI__sync_add_and_fetch: |
1242 | case Builtin::BI__sync_add_and_fetch_1: |
1243 | case Builtin::BI__sync_add_and_fetch_2: |
1244 | case Builtin::BI__sync_add_and_fetch_4: |
1245 | case Builtin::BI__sync_add_and_fetch_8: |
1246 | case Builtin::BI__sync_add_and_fetch_16: |
1247 | case Builtin::BI__sync_sub_and_fetch: |
1248 | case Builtin::BI__sync_sub_and_fetch_1: |
1249 | case Builtin::BI__sync_sub_and_fetch_2: |
1250 | case Builtin::BI__sync_sub_and_fetch_4: |
1251 | case Builtin::BI__sync_sub_and_fetch_8: |
1252 | case Builtin::BI__sync_sub_and_fetch_16: |
1253 | case Builtin::BI__sync_and_and_fetch: |
1254 | case Builtin::BI__sync_and_and_fetch_1: |
1255 | case Builtin::BI__sync_and_and_fetch_2: |
1256 | case Builtin::BI__sync_and_and_fetch_4: |
1257 | case Builtin::BI__sync_and_and_fetch_8: |
1258 | case Builtin::BI__sync_and_and_fetch_16: |
1259 | case Builtin::BI__sync_or_and_fetch: |
1260 | case Builtin::BI__sync_or_and_fetch_1: |
1261 | case Builtin::BI__sync_or_and_fetch_2: |
1262 | case Builtin::BI__sync_or_and_fetch_4: |
1263 | case Builtin::BI__sync_or_and_fetch_8: |
1264 | case Builtin::BI__sync_or_and_fetch_16: |
1265 | case Builtin::BI__sync_xor_and_fetch: |
1266 | case Builtin::BI__sync_xor_and_fetch_1: |
1267 | case Builtin::BI__sync_xor_and_fetch_2: |
1268 | case Builtin::BI__sync_xor_and_fetch_4: |
1269 | case Builtin::BI__sync_xor_and_fetch_8: |
1270 | case Builtin::BI__sync_xor_and_fetch_16: |
1271 | case Builtin::BI__sync_nand_and_fetch: |
1272 | case Builtin::BI__sync_nand_and_fetch_1: |
1273 | case Builtin::BI__sync_nand_and_fetch_2: |
1274 | case Builtin::BI__sync_nand_and_fetch_4: |
1275 | case Builtin::BI__sync_nand_and_fetch_8: |
1276 | case Builtin::BI__sync_nand_and_fetch_16: |
1277 | case Builtin::BI__sync_val_compare_and_swap: |
1278 | case Builtin::BI__sync_val_compare_and_swap_1: |
1279 | case Builtin::BI__sync_val_compare_and_swap_2: |
1280 | case Builtin::BI__sync_val_compare_and_swap_4: |
1281 | case Builtin::BI__sync_val_compare_and_swap_8: |
1282 | case Builtin::BI__sync_val_compare_and_swap_16: |
1283 | case Builtin::BI__sync_bool_compare_and_swap: |
1284 | case Builtin::BI__sync_bool_compare_and_swap_1: |
1285 | case Builtin::BI__sync_bool_compare_and_swap_2: |
1286 | case Builtin::BI__sync_bool_compare_and_swap_4: |
1287 | case Builtin::BI__sync_bool_compare_and_swap_8: |
1288 | case Builtin::BI__sync_bool_compare_and_swap_16: |
1289 | case Builtin::BI__sync_lock_test_and_set: |
1290 | case Builtin::BI__sync_lock_test_and_set_1: |
1291 | case Builtin::BI__sync_lock_test_and_set_2: |
1292 | case Builtin::BI__sync_lock_test_and_set_4: |
1293 | case Builtin::BI__sync_lock_test_and_set_8: |
1294 | case Builtin::BI__sync_lock_test_and_set_16: |
1295 | case Builtin::BI__sync_lock_release: |
1296 | case Builtin::BI__sync_lock_release_1: |
1297 | case Builtin::BI__sync_lock_release_2: |
1298 | case Builtin::BI__sync_lock_release_4: |
1299 | case Builtin::BI__sync_lock_release_8: |
1300 | case Builtin::BI__sync_lock_release_16: |
1301 | case Builtin::BI__sync_swap: |
1302 | case Builtin::BI__sync_swap_1: |
1303 | case Builtin::BI__sync_swap_2: |
1304 | case Builtin::BI__sync_swap_4: |
1305 | case Builtin::BI__sync_swap_8: |
1306 | case Builtin::BI__sync_swap_16: |
1307 | return SemaBuiltinAtomicOverloaded(TheCallResult); |
1308 | case Builtin::BI__sync_synchronize: |
1309 | Diag(TheCall->getBeginLoc(), diag::warn_atomic_implicit_seq_cst) |
1310 | << TheCall->getCallee()->getSourceRange(); |
1311 | break; |
1312 | case Builtin::BI__builtin_nontemporal_load: |
1313 | case Builtin::BI__builtin_nontemporal_store: |
1314 | return SemaBuiltinNontemporalOverloaded(TheCallResult); |
1315 | #define BUILTIN(ID, TYPE, ATTRS) |
1316 | #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ |
1317 | case Builtin::BI##ID: \ |
1318 | return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID); |
1319 | #include "clang/Basic/Builtins.def" |
1320 | case Builtin::BI__annotation: |
1321 | if (SemaBuiltinMSVCAnnotation(*this, TheCall)) |
1322 | return ExprError(); |
1323 | break; |
1324 | case Builtin::BI__builtin_annotation: |
1325 | if (SemaBuiltinAnnotation(*this, TheCall)) |
1326 | return ExprError(); |
1327 | break; |
1328 | case Builtin::BI__builtin_addressof: |
1329 | if (SemaBuiltinAddressof(*this, TheCall)) |
1330 | return ExprError(); |
1331 | break; |
1332 | case Builtin::BI__builtin_add_overflow: |
1333 | case Builtin::BI__builtin_sub_overflow: |
1334 | case Builtin::BI__builtin_mul_overflow: |
1335 | if (SemaBuiltinOverflow(*this, TheCall)) |
1336 | return ExprError(); |
1337 | break; |
1338 | case Builtin::BI__builtin_operator_new: |
1339 | case Builtin::BI__builtin_operator_delete: { |
1340 | bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete; |
1341 | ExprResult Res = |
1342 | SemaBuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete); |
1343 | if (Res.isInvalid()) |
1344 | CorrectDelayedTyposInExpr(TheCallResult.get()); |
1345 | return Res; |
1346 | } |
1347 | case Builtin::BI__builtin_dump_struct: { |
1348 | |
1349 | if (checkArgCount(*this, TheCall, 2)) |
1350 | return ExprError(); |
1351 | |
1352 | const Expr *PtrArg = TheCall->getArg(0)->IgnoreParenImpCasts(); |
1353 | const QualType PtrArgType = PtrArg->getType(); |
1354 | if (!PtrArgType->isPointerType() || |
1355 | !PtrArgType->getPointeeType()->isRecordType()) { |
1356 | Diag(PtrArg->getBeginLoc(), diag::err_typecheck_convert_incompatible) |
1357 | << PtrArgType << "structure pointer" << 1 << 0 << 3 << 1 << PtrArgType |
1358 | << "structure pointer"; |
1359 | return ExprError(); |
1360 | } |
1361 | |
1362 | |
1363 | const Expr *FnPtrArg = TheCall->getArg(1)->IgnoreImpCasts(); |
1364 | const QualType FnPtrArgType = FnPtrArg->getType(); |
1365 | if (!FnPtrArgType->isPointerType()) { |
1366 | Diag(FnPtrArg->getBeginLoc(), diag::err_typecheck_convert_incompatible) |
1367 | << FnPtrArgType << "'int (*)(const char *, ...)'" << 1 << 0 << 3 << 2 |
1368 | << FnPtrArgType << "'int (*)(const char *, ...)'"; |
1369 | return ExprError(); |
1370 | } |
1371 | |
1372 | const auto *FuncType = |
1373 | FnPtrArgType->getPointeeType()->getAs<FunctionType>(); |
1374 | |
1375 | if (!FuncType) { |
1376 | Diag(FnPtrArg->getBeginLoc(), diag::err_typecheck_convert_incompatible) |
1377 | << FnPtrArgType << "'int (*)(const char *, ...)'" << 1 << 0 << 3 << 2 |
1378 | << FnPtrArgType << "'int (*)(const char *, ...)'"; |
1379 | return ExprError(); |
1380 | } |
1381 | |
1382 | if (const auto *FT = dyn_cast<FunctionProtoType>(FuncType)) { |
1383 | if (!FT->getNumParams()) { |
1384 | Diag(FnPtrArg->getBeginLoc(), diag::err_typecheck_convert_incompatible) |
1385 | << FnPtrArgType << "'int (*)(const char *, ...)'" << 1 << 0 << 3 |
1386 | << 2 << FnPtrArgType << "'int (*)(const char *, ...)'"; |
1387 | return ExprError(); |
1388 | } |
1389 | QualType PT = FT->getParamType(0); |
1390 | if (!FT->isVariadic() || FT->getReturnType() != Context.IntTy || |
1391 | !PT->isPointerType() || !PT->getPointeeType()->isCharType() || |
1392 | !PT->getPointeeType().isConstQualified()) { |
1393 | Diag(FnPtrArg->getBeginLoc(), diag::err_typecheck_convert_incompatible) |
1394 | << FnPtrArgType << "'int (*)(const char *, ...)'" << 1 << 0 << 3 |
1395 | << 2 << FnPtrArgType << "'int (*)(const char *, ...)'"; |
1396 | return ExprError(); |
1397 | } |
1398 | } |
1399 | |
1400 | TheCall->setType(Context.IntTy); |
1401 | break; |
1402 | } |
1403 | case Builtin::BI__builtin_call_with_static_chain: |
1404 | if (SemaBuiltinCallWithStaticChain(*this, TheCall)) |
1405 | return ExprError(); |
1406 | break; |
1407 | case Builtin::BI__exception_code: |
1408 | case Builtin::BI_exception_code: |
1409 | if (SemaBuiltinSEHScopeCheck(*this, TheCall, Scope::SEHExceptScope, |
1410 | diag::err_seh___except_block)) |
1411 | return ExprError(); |
1412 | break; |
1413 | case Builtin::BI__exception_info: |
1414 | case Builtin::BI_exception_info: |
1415 | if (SemaBuiltinSEHScopeCheck(*this, TheCall, Scope::SEHFilterScope, |
1416 | diag::err_seh___except_filter)) |
1417 | return ExprError(); |
1418 | break; |
1419 | case Builtin::BI__GetExceptionInfo: |
1420 | if (checkArgCount(*this, TheCall, 1)) |
1421 | return ExprError(); |
1422 | |
1423 | if (CheckCXXThrowOperand( |
1424 | TheCall->getBeginLoc(), |
1425 | Context.getExceptionObjectType(FDecl->getParamDecl(0)->getType()), |
1426 | TheCall)) |
1427 | return ExprError(); |
1428 | |
1429 | TheCall->setType(Context.VoidPtrTy); |
1430 | break; |
1431 | |
1432 | case Builtin::BIread_pipe: |
1433 | case Builtin::BIwrite_pipe: |
1434 | |
1435 | |
1436 | if (SemaBuiltinRWPipe(*this, TheCall)) |
1437 | return ExprError(); |
1438 | break; |
1439 | case Builtin::BIreserve_read_pipe: |
1440 | case Builtin::BIreserve_write_pipe: |
1441 | case Builtin::BIwork_group_reserve_read_pipe: |
1442 | case Builtin::BIwork_group_reserve_write_pipe: |
1443 | if (SemaBuiltinReserveRWPipe(*this, TheCall)) |
1444 | return ExprError(); |
1445 | break; |
1446 | case Builtin::BIsub_group_reserve_read_pipe: |
1447 | case Builtin::BIsub_group_reserve_write_pipe: |
1448 | if (checkOpenCLSubgroupExt(*this, TheCall) || |
1449 | SemaBuiltinReserveRWPipe(*this, TheCall)) |
1450 | return ExprError(); |
1451 | break; |
1452 | case Builtin::BIcommit_read_pipe: |
1453 | case Builtin::BIcommit_write_pipe: |
1454 | case Builtin::BIwork_group_commit_read_pipe: |
1455 | case Builtin::BIwork_group_commit_write_pipe: |
1456 | if (SemaBuiltinCommitRWPipe(*this, TheCall)) |
1457 | return ExprError(); |
1458 | break; |
1459 | case Builtin::BIsub_group_commit_read_pipe: |
1460 | case Builtin::BIsub_group_commit_write_pipe: |
1461 | if (checkOpenCLSubgroupExt(*this, TheCall) || |
1462 | SemaBuiltinCommitRWPipe(*this, TheCall)) |
1463 | return ExprError(); |
1464 | break; |
1465 | case Builtin::BIget_pipe_num_packets: |
1466 | case Builtin::BIget_pipe_max_packets: |
1467 | if (SemaBuiltinPipePackets(*this, TheCall)) |
1468 | return ExprError(); |
1469 | break; |
1470 | case Builtin::BIto_global: |
1471 | case Builtin::BIto_local: |
1472 | case Builtin::BIto_private: |
1473 | if (SemaOpenCLBuiltinToAddr(*this, BuiltinID, TheCall)) |
1474 | return ExprError(); |
1475 | break; |
1476 | |
1477 | case Builtin::BIenqueue_kernel: |
1478 | if (SemaOpenCLBuiltinEnqueueKernel(*this, TheCall)) |
1479 | return ExprError(); |
1480 | break; |
1481 | case Builtin::BIget_kernel_work_group_size: |
1482 | case Builtin::BIget_kernel_preferred_work_group_size_multiple: |
1483 | if (SemaOpenCLBuiltinKernelWorkGroupSize(*this, TheCall)) |
1484 | return ExprError(); |
1485 | break; |
1486 | case Builtin::BIget_kernel_max_sub_group_size_for_ndrange: |
1487 | case Builtin::BIget_kernel_sub_group_count_for_ndrange: |
1488 | if (SemaOpenCLBuiltinNDRangeAndBlock(*this, TheCall)) |
1489 | return ExprError(); |
1490 | break; |
1491 | case Builtin::BI__builtin_os_log_format: |
1492 | case Builtin::BI__builtin_os_log_format_buffer_size: |
1493 | if (SemaBuiltinOSLogFormat(TheCall)) |
1494 | return ExprError(); |
1495 | break; |
1496 | } |
1497 | |
1498 | |
1499 | |
1500 | if (Context.BuiltinInfo.isTSBuiltin(BuiltinID)) { |
1501 | switch (Context.getTargetInfo().getTriple().getArch()) { |
1502 | case llvm::Triple::arm: |
1503 | case llvm::Triple::armeb: |
1504 | case llvm::Triple::thumb: |
1505 | case llvm::Triple::thumbeb: |
1506 | if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall)) |
1507 | return ExprError(); |
1508 | break; |
1509 | case llvm::Triple::aarch64: |
1510 | case llvm::Triple::aarch64_be: |
1511 | if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall)) |
1512 | return ExprError(); |
1513 | break; |
1514 | case llvm::Triple::hexagon: |
1515 | if (CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall)) |
1516 | return ExprError(); |
1517 | break; |
1518 | case llvm::Triple::mips: |
1519 | case llvm::Triple::mipsel: |
1520 | case llvm::Triple::mips64: |
1521 | case llvm::Triple::mips64el: |
1522 | if (CheckMipsBuiltinFunctionCall(BuiltinID, TheCall)) |
1523 | return ExprError(); |
1524 | break; |
1525 | case llvm::Triple::systemz: |
1526 | if (CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall)) |
1527 | return ExprError(); |
1528 | break; |
1529 | case llvm::Triple::x86: |
1530 | case llvm::Triple::x86_64: |
1531 | if (CheckX86BuiltinFunctionCall(BuiltinID, TheCall)) |
1532 | return ExprError(); |
1533 | break; |
1534 | case llvm::Triple::ppc: |
1535 | case llvm::Triple::ppc64: |
1536 | case llvm::Triple::ppc64le: |
1537 | if (CheckPPCBuiltinFunctionCall(BuiltinID, TheCall)) |
1538 | return ExprError(); |
1539 | break; |
1540 | default: |
1541 | break; |
1542 | } |
1543 | } |
1544 | |
1545 | return TheCallResult; |
1546 | } |
1547 | |
1548 | |
1549 | static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { |
1550 | NeonTypeFlags Type(t); |
1551 | int IsQuad = ForceQuad ? true : Type.isQuad(); |
1552 | switch (Type.getEltType()) { |
1553 | case NeonTypeFlags::Int8: |
1554 | case NeonTypeFlags::Poly8: |
1555 | return shift ? 7 : (8 << IsQuad) - 1; |
1556 | case NeonTypeFlags::Int16: |
1557 | case NeonTypeFlags::Poly16: |
1558 | return shift ? 15 : (4 << IsQuad) - 1; |
1559 | case NeonTypeFlags::Int32: |
1560 | return shift ? 31 : (2 << IsQuad) - 1; |
1561 | case NeonTypeFlags::Int64: |
1562 | case NeonTypeFlags::Poly64: |
1563 | return shift ? 63 : (1 << IsQuad) - 1; |
1564 | case NeonTypeFlags::Poly128: |
1565 | return shift ? 127 : (1 << IsQuad) - 1; |
1566 | case NeonTypeFlags::Float16: |
1567 | (0) . __assert_fail ("!shift && \"cannot shift float types!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1567, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!shift && "cannot shift float types!"); |
1568 | return (4 << IsQuad) - 1; |
1569 | case NeonTypeFlags::Float32: |
1570 | (0) . __assert_fail ("!shift && \"cannot shift float types!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1570, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!shift && "cannot shift float types!"); |
1571 | return (2 << IsQuad) - 1; |
1572 | case NeonTypeFlags::Float64: |
1573 | (0) . __assert_fail ("!shift && \"cannot shift float types!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1573, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!shift && "cannot shift float types!"); |
1574 | return (1 << IsQuad) - 1; |
1575 | } |
1576 | llvm_unreachable("Invalid NeonTypeFlag!"); |
1577 | } |
1578 | |
1579 | |
1580 | |
1581 | |
1582 | static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, |
1583 | bool IsPolyUnsigned, bool IsInt64Long) { |
1584 | switch (Flags.getEltType()) { |
1585 | case NeonTypeFlags::Int8: |
1586 | return Flags.isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy; |
1587 | case NeonTypeFlags::Int16: |
1588 | return Flags.isUnsigned() ? Context.UnsignedShortTy : Context.ShortTy; |
1589 | case NeonTypeFlags::Int32: |
1590 | return Flags.isUnsigned() ? Context.UnsignedIntTy : Context.IntTy; |
1591 | case NeonTypeFlags::Int64: |
1592 | if (IsInt64Long) |
1593 | return Flags.isUnsigned() ? Context.UnsignedLongTy : Context.LongTy; |
1594 | else |
1595 | return Flags.isUnsigned() ? Context.UnsignedLongLongTy |
1596 | : Context.LongLongTy; |
1597 | case NeonTypeFlags::Poly8: |
1598 | return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy; |
1599 | case NeonTypeFlags::Poly16: |
1600 | return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy; |
1601 | case NeonTypeFlags::Poly64: |
1602 | if (IsInt64Long) |
1603 | return Context.UnsignedLongTy; |
1604 | else |
1605 | return Context.UnsignedLongLongTy; |
1606 | case NeonTypeFlags::Poly128: |
1607 | break; |
1608 | case NeonTypeFlags::Float16: |
1609 | return Context.HalfTy; |
1610 | case NeonTypeFlags::Float32: |
1611 | return Context.FloatTy; |
1612 | case NeonTypeFlags::Float64: |
1613 | return Context.DoubleTy; |
1614 | } |
1615 | llvm_unreachable("Invalid NeonTypeFlag!"); |
1616 | } |
1617 | |
1618 | bool Sema::CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { |
1619 | llvm::APSInt Result; |
1620 | uint64_t mask = 0; |
1621 | unsigned TV = 0; |
1622 | int PtrArgNum = -1; |
1623 | bool HasConstPtr = false; |
1624 | switch (BuiltinID) { |
1625 | #define GET_NEON_OVERLOAD_CHECK |
1626 | #include "clang/Basic/arm_neon.inc" |
1627 | #include "clang/Basic/arm_fp16.inc" |
1628 | #undef GET_NEON_OVERLOAD_CHECK |
1629 | } |
1630 | |
1631 | |
1632 | |
1633 | unsigned ImmArg = TheCall->getNumArgs()-1; |
1634 | if (mask) { |
1635 | if (SemaBuiltinConstantArg(TheCall, ImmArg, Result)) |
1636 | return true; |
1637 | |
1638 | TV = Result.getLimitedValue(64); |
1639 | if ((TV > 63) || (mask & (1ULL << TV)) == 0) |
1640 | return Diag(TheCall->getBeginLoc(), diag::err_invalid_neon_type_code) |
1641 | << TheCall->getArg(ImmArg)->getSourceRange(); |
1642 | } |
1643 | |
1644 | if (PtrArgNum >= 0) { |
1645 | |
1646 | Expr *Arg = TheCall->getArg(PtrArgNum); |
1647 | if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) |
1648 | Arg = ICE->getSubExpr(); |
1649 | ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); |
1650 | QualType RHSTy = RHS.get()->getType(); |
1651 | |
1652 | llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch(); |
1653 | bool IsPolyUnsigned = Arch == llvm::Triple::aarch64 || |
1654 | Arch == llvm::Triple::aarch64_be; |
1655 | bool IsInt64Long = |
1656 | Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong; |
1657 | QualType EltTy = |
1658 | getNeonEltType(NeonTypeFlags(TV), Context, IsPolyUnsigned, IsInt64Long); |
1659 | if (HasConstPtr) |
1660 | EltTy = EltTy.withConst(); |
1661 | QualType LHSTy = Context.getPointerType(EltTy); |
1662 | AssignConvertType ConvTy; |
1663 | ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS); |
1664 | if (RHS.isInvalid()) |
1665 | return true; |
1666 | if (DiagnoseAssignmentResult(ConvTy, Arg->getBeginLoc(), LHSTy, RHSTy, |
1667 | RHS.get(), AA_Assigning)) |
1668 | return true; |
1669 | } |
1670 | |
1671 | |
1672 | |
1673 | unsigned i = 0, l = 0, u = 0; |
1674 | switch (BuiltinID) { |
1675 | default: |
1676 | return false; |
1677 | #define GET_NEON_IMMEDIATE_CHECK |
1678 | #include "clang/Basic/arm_neon.inc" |
1679 | #include "clang/Basic/arm_fp16.inc" |
1680 | #undef GET_NEON_IMMEDIATE_CHECK |
1681 | } |
1682 | |
1683 | return SemaBuiltinConstantArgRange(TheCall, i, l, u + l); |
1684 | } |
1685 | |
1686 | bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, |
1687 | unsigned MaxWidth) { |
1688 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((BuiltinID == ARM::BI__builtin_arm_ldrex || |
1689 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == ARM::BI__builtin_arm_ldaex || |
1690 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == ARM::BI__builtin_arm_strex || |
1691 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == ARM::BI__builtin_arm_stlex || |
1692 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == AArch64::BI__builtin_arm_ldrex || |
1693 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == AArch64::BI__builtin_arm_ldaex || |
1694 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == AArch64::BI__builtin_arm_strex || |
1695 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == AArch64::BI__builtin_arm_stlex) && |
1696 | (0) . __assert_fail ("(BuiltinID == ARM..BI__builtin_arm_ldrex || BuiltinID == ARM..BI__builtin_arm_ldaex || BuiltinID == ARM..BI__builtin_arm_strex || BuiltinID == ARM..BI__builtin_arm_stlex || BuiltinID == AArch64..BI__builtin_arm_ldrex || BuiltinID == AArch64..BI__builtin_arm_ldaex || BuiltinID == AArch64..BI__builtin_arm_strex || BuiltinID == AArch64..BI__builtin_arm_stlex) && \"unexpected ARM builtin\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1696, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "unexpected ARM builtin"); |
1697 | bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex || |
1698 | BuiltinID == ARM::BI__builtin_arm_ldaex || |
1699 | BuiltinID == AArch64::BI__builtin_arm_ldrex || |
1700 | BuiltinID == AArch64::BI__builtin_arm_ldaex; |
1701 | |
1702 | DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); |
1703 | |
1704 | |
1705 | if (checkArgCount(*this, TheCall, IsLdrex ? 1 : 2)) |
1706 | return true; |
1707 | |
1708 | |
1709 | |
1710 | |
1711 | |
1712 | Expr *PointerArg = TheCall->getArg(IsLdrex ? 0 : 1); |
1713 | ExprResult PointerArgRes = DefaultFunctionArrayLvalueConversion(PointerArg); |
1714 | if (PointerArgRes.isInvalid()) |
1715 | return true; |
1716 | PointerArg = PointerArgRes.get(); |
1717 | |
1718 | const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>(); |
1719 | if (!pointerType) { |
1720 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) |
1721 | << PointerArg->getType() << PointerArg->getSourceRange(); |
1722 | return true; |
1723 | } |
1724 | |
1725 | |
1726 | |
1727 | |
1728 | QualType ValType = pointerType->getPointeeType(); |
1729 | QualType AddrType = ValType.getUnqualifiedType().withVolatile(); |
1730 | if (IsLdrex) |
1731 | AddrType.addConst(); |
1732 | |
1733 | |
1734 | CastKind CastNeeded = CK_NoOp; |
1735 | if (!AddrType.isAtLeastAsQualifiedAs(ValType)) { |
1736 | CastNeeded = CK_BitCast; |
1737 | Diag(DRE->getBeginLoc(), diag::ext_typecheck_convert_discards_qualifiers) |
1738 | << PointerArg->getType() << Context.getPointerType(AddrType) |
1739 | << AA_Passing << PointerArg->getSourceRange(); |
1740 | } |
1741 | |
1742 | |
1743 | AddrType = Context.getPointerType(AddrType); |
1744 | PointerArgRes = ImpCastExprToType(PointerArg, AddrType, CastNeeded); |
1745 | if (PointerArgRes.isInvalid()) |
1746 | return true; |
1747 | PointerArg = PointerArgRes.get(); |
1748 | |
1749 | TheCall->setArg(IsLdrex ? 0 : 1, PointerArg); |
1750 | |
1751 | |
1752 | if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && |
1753 | !ValType->isBlockPointerType() && !ValType->isFloatingType()) { |
1754 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intfltptr) |
1755 | << PointerArg->getType() << PointerArg->getSourceRange(); |
1756 | return true; |
1757 | } |
1758 | |
1759 | |
1760 | if (Context.getTypeSize(ValType) > MaxWidth) { |
1761 | (0) . __assert_fail ("MaxWidth == 64 && \"Diagnostic unexpectedly inaccurate\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 1761, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(MaxWidth == 64 && "Diagnostic unexpectedly inaccurate"); |
1762 | Diag(DRE->getBeginLoc(), diag::err_atomic_exclusive_builtin_pointer_size) |
1763 | << PointerArg->getType() << PointerArg->getSourceRange(); |
1764 | return true; |
1765 | } |
1766 | |
1767 | switch (ValType.getObjCLifetime()) { |
1768 | case Qualifiers::OCL_None: |
1769 | case Qualifiers::OCL_ExplicitNone: |
1770 | |
1771 | break; |
1772 | |
1773 | case Qualifiers::OCL_Weak: |
1774 | case Qualifiers::OCL_Strong: |
1775 | case Qualifiers::OCL_Autoreleasing: |
1776 | Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership) |
1777 | << ValType << PointerArg->getSourceRange(); |
1778 | return true; |
1779 | } |
1780 | |
1781 | if (IsLdrex) { |
1782 | TheCall->setType(ValType); |
1783 | return false; |
1784 | } |
1785 | |
1786 | |
1787 | ExprResult ValArg = TheCall->getArg(0); |
1788 | InitializedEntity Entity = InitializedEntity::InitializeParameter( |
1789 | Context, ValType, false); |
1790 | ValArg = PerformCopyInitialization(Entity, SourceLocation(), ValArg); |
1791 | if (ValArg.isInvalid()) |
1792 | return true; |
1793 | TheCall->setArg(0, ValArg.get()); |
1794 | |
1795 | |
1796 | |
1797 | TheCall->setType(Context.IntTy); |
1798 | return false; |
1799 | } |
1800 | |
1801 | bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { |
1802 | if (BuiltinID == ARM::BI__builtin_arm_ldrex || |
1803 | BuiltinID == ARM::BI__builtin_arm_ldaex || |
1804 | BuiltinID == ARM::BI__builtin_arm_strex || |
1805 | BuiltinID == ARM::BI__builtin_arm_stlex) { |
1806 | return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64); |
1807 | } |
1808 | |
1809 | if (BuiltinID == ARM::BI__builtin_arm_prefetch) { |
1810 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || |
1811 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 1); |
1812 | } |
1813 | |
1814 | if (BuiltinID == ARM::BI__builtin_arm_rsr64 || |
1815 | BuiltinID == ARM::BI__builtin_arm_wsr64) |
1816 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 3, false); |
1817 | |
1818 | if (BuiltinID == ARM::BI__builtin_arm_rsr || |
1819 | BuiltinID == ARM::BI__builtin_arm_rsrp || |
1820 | BuiltinID == ARM::BI__builtin_arm_wsr || |
1821 | BuiltinID == ARM::BI__builtin_arm_wsrp) |
1822 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); |
1823 | |
1824 | if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) |
1825 | return true; |
1826 | |
1827 | |
1828 | |
1829 | |
1830 | switch (BuiltinID) { |
1831 | default: return false; |
1832 | case ARM::BI__builtin_arm_ssat: |
1833 | return SemaBuiltinConstantArgRange(TheCall, 1, 1, 32); |
1834 | case ARM::BI__builtin_arm_usat: |
1835 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 31); |
1836 | case ARM::BI__builtin_arm_ssat16: |
1837 | return SemaBuiltinConstantArgRange(TheCall, 1, 1, 16); |
1838 | case ARM::BI__builtin_arm_usat16: |
1839 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15); |
1840 | case ARM::BI__builtin_arm_vcvtr_f: |
1841 | case ARM::BI__builtin_arm_vcvtr_d: |
1842 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1); |
1843 | case ARM::BI__builtin_arm_dmb: |
1844 | case ARM::BI__builtin_arm_dsb: |
1845 | case ARM::BI__builtin_arm_isb: |
1846 | case ARM::BI__builtin_arm_dbg: |
1847 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 15); |
1848 | } |
1849 | } |
1850 | |
1851 | bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, |
1852 | CallExpr *TheCall) { |
1853 | if (BuiltinID == AArch64::BI__builtin_arm_ldrex || |
1854 | BuiltinID == AArch64::BI__builtin_arm_ldaex || |
1855 | BuiltinID == AArch64::BI__builtin_arm_strex || |
1856 | BuiltinID == AArch64::BI__builtin_arm_stlex) { |
1857 | return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128); |
1858 | } |
1859 | |
1860 | if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { |
1861 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || |
1862 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 2) || |
1863 | SemaBuiltinConstantArgRange(TheCall, 3, 0, 1) || |
1864 | SemaBuiltinConstantArgRange(TheCall, 4, 0, 1); |
1865 | } |
1866 | |
1867 | if (BuiltinID == AArch64::BI__builtin_arm_rsr64 || |
1868 | BuiltinID == AArch64::BI__builtin_arm_wsr64) |
1869 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); |
1870 | |
1871 | if (BuiltinID == AArch64::BI__builtin_arm_rsr || |
1872 | BuiltinID == AArch64::BI__builtin_arm_rsrp || |
1873 | BuiltinID == AArch64::BI__builtin_arm_wsr || |
1874 | BuiltinID == AArch64::BI__builtin_arm_wsrp) |
1875 | return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); |
1876 | |
1877 | |
1878 | |
1879 | |
1880 | if (BuiltinID == AArch64::BI_ReadStatusReg || |
1881 | BuiltinID == AArch64::BI_WriteStatusReg) |
1882 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 0x7fff); |
1883 | |
1884 | if (BuiltinID == AArch64::BI__getReg) |
1885 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31); |
1886 | |
1887 | if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) |
1888 | return true; |
1889 | |
1890 | |
1891 | |
1892 | unsigned i = 0, l = 0, u = 0; |
1893 | switch (BuiltinID) { |
1894 | default: return false; |
1895 | case AArch64::BI__builtin_arm_dmb: |
1896 | case AArch64::BI__builtin_arm_dsb: |
1897 | case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break; |
1898 | } |
1899 | |
1900 | return SemaBuiltinConstantArgRange(TheCall, i, l, u + l); |
1901 | } |
1902 | |
1903 | bool Sema::CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall) { |
1904 | struct BuiltinAndString { |
1905 | unsigned BuiltinID; |
1906 | const char *Str; |
1907 | }; |
1908 | |
1909 | static BuiltinAndString ValidCPU[] = { |
1910 | { Hexagon::BI__builtin_HEXAGON_A6_vcmpbeq_notany, "v65,v66" }, |
1911 | { Hexagon::BI__builtin_HEXAGON_A6_vminub_RdP, "v62,v65,v66" }, |
1912 | { Hexagon::BI__builtin_HEXAGON_F2_dfadd, "v66" }, |
1913 | { Hexagon::BI__builtin_HEXAGON_F2_dfsub, "v66" }, |
1914 | { Hexagon::BI__builtin_HEXAGON_M2_mnaci, "v66" }, |
1915 | { Hexagon::BI__builtin_HEXAGON_M6_vabsdiffb, "v62,v65,v66" }, |
1916 | { Hexagon::BI__builtin_HEXAGON_M6_vabsdiffub, "v62,v65,v66" }, |
1917 | { Hexagon::BI__builtin_HEXAGON_S2_mask, "v66" }, |
1918 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_acc, "v60,v62,v65,v66" }, |
1919 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_and, "v60,v62,v65,v66" }, |
1920 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_nac, "v60,v62,v65,v66" }, |
1921 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_or, "v60,v62,v65,v66" }, |
1922 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p, "v60,v62,v65,v66" }, |
1923 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_xacc, "v60,v62,v65,v66" }, |
1924 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_acc, "v60,v62,v65,v66" }, |
1925 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_and, "v60,v62,v65,v66" }, |
1926 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_nac, "v60,v62,v65,v66" }, |
1927 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_or, "v60,v62,v65,v66" }, |
1928 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r, "v60,v62,v65,v66" }, |
1929 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_xacc, "v60,v62,v65,v66" }, |
1930 | { Hexagon::BI__builtin_HEXAGON_S6_vsplatrbp, "v62,v65,v66" }, |
1931 | { Hexagon::BI__builtin_HEXAGON_S6_vtrunehb_ppp, "v62,v65,v66" }, |
1932 | { Hexagon::BI__builtin_HEXAGON_S6_vtrunohb_ppp, "v62,v65,v66" }, |
1933 | }; |
1934 | |
1935 | static BuiltinAndString ValidHVX[] = { |
1936 | { Hexagon::BI__builtin_HEXAGON_V6_hi, "v60,v62,v65,v66" }, |
1937 | { Hexagon::BI__builtin_HEXAGON_V6_hi_128B, "v60,v62,v65,v66" }, |
1938 | { Hexagon::BI__builtin_HEXAGON_V6_lo, "v60,v62,v65,v66" }, |
1939 | { Hexagon::BI__builtin_HEXAGON_V6_lo_128B, "v60,v62,v65,v66" }, |
1940 | { Hexagon::BI__builtin_HEXAGON_V6_extractw, "v60,v62,v65,v66" }, |
1941 | { Hexagon::BI__builtin_HEXAGON_V6_extractw_128B, "v60,v62,v65,v66" }, |
1942 | { Hexagon::BI__builtin_HEXAGON_V6_lvsplatb, "v62,v65,v66" }, |
1943 | { Hexagon::BI__builtin_HEXAGON_V6_lvsplatb_128B, "v62,v65,v66" }, |
1944 | { Hexagon::BI__builtin_HEXAGON_V6_lvsplath, "v62,v65,v66" }, |
1945 | { Hexagon::BI__builtin_HEXAGON_V6_lvsplath_128B, "v62,v65,v66" }, |
1946 | { Hexagon::BI__builtin_HEXAGON_V6_lvsplatw, "v60,v62,v65,v66" }, |
1947 | { Hexagon::BI__builtin_HEXAGON_V6_lvsplatw_128B, "v60,v62,v65,v66" }, |
1948 | { Hexagon::BI__builtin_HEXAGON_V6_pred_and, "v60,v62,v65,v66" }, |
1949 | { Hexagon::BI__builtin_HEXAGON_V6_pred_and_128B, "v60,v62,v65,v66" }, |
1950 | { Hexagon::BI__builtin_HEXAGON_V6_pred_and_n, "v60,v62,v65,v66" }, |
1951 | { Hexagon::BI__builtin_HEXAGON_V6_pred_and_n_128B, "v60,v62,v65,v66" }, |
1952 | { Hexagon::BI__builtin_HEXAGON_V6_pred_not, "v60,v62,v65,v66" }, |
1953 | { Hexagon::BI__builtin_HEXAGON_V6_pred_not_128B, "v60,v62,v65,v66" }, |
1954 | { Hexagon::BI__builtin_HEXAGON_V6_pred_or, "v60,v62,v65,v66" }, |
1955 | { Hexagon::BI__builtin_HEXAGON_V6_pred_or_128B, "v60,v62,v65,v66" }, |
1956 | { Hexagon::BI__builtin_HEXAGON_V6_pred_or_n, "v60,v62,v65,v66" }, |
1957 | { Hexagon::BI__builtin_HEXAGON_V6_pred_or_n_128B, "v60,v62,v65,v66" }, |
1958 | { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2, "v60,v62,v65,v66" }, |
1959 | { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2_128B, "v60,v62,v65,v66" }, |
1960 | { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2v2, "v62,v65,v66" }, |
1961 | { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2v2_128B, "v62,v65,v66" }, |
1962 | { Hexagon::BI__builtin_HEXAGON_V6_pred_xor, "v60,v62,v65,v66" }, |
1963 | { Hexagon::BI__builtin_HEXAGON_V6_pred_xor_128B, "v60,v62,v65,v66" }, |
1964 | { Hexagon::BI__builtin_HEXAGON_V6_shuffeqh, "v62,v65,v66" }, |
1965 | { Hexagon::BI__builtin_HEXAGON_V6_shuffeqh_128B, "v62,v65,v66" }, |
1966 | { Hexagon::BI__builtin_HEXAGON_V6_shuffeqw, "v62,v65,v66" }, |
1967 | { Hexagon::BI__builtin_HEXAGON_V6_shuffeqw_128B, "v62,v65,v66" }, |
1968 | { Hexagon::BI__builtin_HEXAGON_V6_vabsb, "v65,v66" }, |
1969 | { Hexagon::BI__builtin_HEXAGON_V6_vabsb_128B, "v65,v66" }, |
1970 | { Hexagon::BI__builtin_HEXAGON_V6_vabsb_sat, "v65,v66" }, |
1971 | { Hexagon::BI__builtin_HEXAGON_V6_vabsb_sat_128B, "v65,v66" }, |
1972 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffh, "v60,v62,v65,v66" }, |
1973 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffh_128B, "v60,v62,v65,v66" }, |
1974 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffub, "v60,v62,v65,v66" }, |
1975 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffub_128B, "v60,v62,v65,v66" }, |
1976 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffuh, "v60,v62,v65,v66" }, |
1977 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffuh_128B, "v60,v62,v65,v66" }, |
1978 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffw, "v60,v62,v65,v66" }, |
1979 | { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffw_128B, "v60,v62,v65,v66" }, |
1980 | { Hexagon::BI__builtin_HEXAGON_V6_vabsh, "v60,v62,v65,v66" }, |
1981 | { Hexagon::BI__builtin_HEXAGON_V6_vabsh_128B, "v60,v62,v65,v66" }, |
1982 | { Hexagon::BI__builtin_HEXAGON_V6_vabsh_sat, "v60,v62,v65,v66" }, |
1983 | { Hexagon::BI__builtin_HEXAGON_V6_vabsh_sat_128B, "v60,v62,v65,v66" }, |
1984 | { Hexagon::BI__builtin_HEXAGON_V6_vabsw, "v60,v62,v65,v66" }, |
1985 | { Hexagon::BI__builtin_HEXAGON_V6_vabsw_128B, "v60,v62,v65,v66" }, |
1986 | { Hexagon::BI__builtin_HEXAGON_V6_vabsw_sat, "v60,v62,v65,v66" }, |
1987 | { Hexagon::BI__builtin_HEXAGON_V6_vabsw_sat_128B, "v60,v62,v65,v66" }, |
1988 | { Hexagon::BI__builtin_HEXAGON_V6_vaddb, "v60,v62,v65,v66" }, |
1989 | { Hexagon::BI__builtin_HEXAGON_V6_vaddb_128B, "v60,v62,v65,v66" }, |
1990 | { Hexagon::BI__builtin_HEXAGON_V6_vaddb_dv, "v60,v62,v65,v66" }, |
1991 | { Hexagon::BI__builtin_HEXAGON_V6_vaddb_dv_128B, "v60,v62,v65,v66" }, |
1992 | { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat, "v62,v65,v66" }, |
1993 | { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_128B, "v62,v65,v66" }, |
1994 | { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_dv, "v62,v65,v66" }, |
1995 | { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_dv_128B, "v62,v65,v66" }, |
1996 | { Hexagon::BI__builtin_HEXAGON_V6_vaddcarry, "v62,v65,v66" }, |
1997 | { Hexagon::BI__builtin_HEXAGON_V6_vaddcarry_128B, "v62,v65,v66" }, |
1998 | { Hexagon::BI__builtin_HEXAGON_V6_vaddcarrysat, "v66" }, |
1999 | { Hexagon::BI__builtin_HEXAGON_V6_vaddcarrysat_128B, "v66" }, |
2000 | { Hexagon::BI__builtin_HEXAGON_V6_vaddclbh, "v62,v65,v66" }, |
2001 | { Hexagon::BI__builtin_HEXAGON_V6_vaddclbh_128B, "v62,v65,v66" }, |
2002 | { Hexagon::BI__builtin_HEXAGON_V6_vaddclbw, "v62,v65,v66" }, |
2003 | { Hexagon::BI__builtin_HEXAGON_V6_vaddclbw_128B, "v62,v65,v66" }, |
2004 | { Hexagon::BI__builtin_HEXAGON_V6_vaddh, "v60,v62,v65,v66" }, |
2005 | { Hexagon::BI__builtin_HEXAGON_V6_vaddh_128B, "v60,v62,v65,v66" }, |
2006 | { Hexagon::BI__builtin_HEXAGON_V6_vaddh_dv, "v60,v62,v65,v66" }, |
2007 | { Hexagon::BI__builtin_HEXAGON_V6_vaddh_dv_128B, "v60,v62,v65,v66" }, |
2008 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat, "v60,v62,v65,v66" }, |
2009 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_128B, "v60,v62,v65,v66" }, |
2010 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_dv, "v60,v62,v65,v66" }, |
2011 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_dv_128B, "v60,v62,v65,v66" }, |
2012 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhw, "v60,v62,v65,v66" }, |
2013 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_128B, "v60,v62,v65,v66" }, |
2014 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_acc, "v62,v65,v66" }, |
2015 | { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_acc_128B, "v62,v65,v66" }, |
2016 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubh, "v60,v62,v65,v66" }, |
2017 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_128B, "v60,v62,v65,v66" }, |
2018 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_acc, "v62,v65,v66" }, |
2019 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_acc_128B, "v62,v65,v66" }, |
2020 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat, "v60,v62,v65,v66" }, |
2021 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_128B, "v60,v62,v65,v66" }, |
2022 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_dv, "v60,v62,v65,v66" }, |
2023 | { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_dv_128B, "v60,v62,v65,v66" }, |
2024 | { Hexagon::BI__builtin_HEXAGON_V6_vaddububb_sat, "v62,v65,v66" }, |
2025 | { Hexagon::BI__builtin_HEXAGON_V6_vaddububb_sat_128B, "v62,v65,v66" }, |
2026 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat, "v60,v62,v65,v66" }, |
2027 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_128B, "v60,v62,v65,v66" }, |
2028 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_dv, "v60,v62,v65,v66" }, |
2029 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_dv_128B, "v60,v62,v65,v66" }, |
2030 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhw, "v60,v62,v65,v66" }, |
2031 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_128B, "v60,v62,v65,v66" }, |
2032 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_acc, "v62,v65,v66" }, |
2033 | { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_acc_128B, "v62,v65,v66" }, |
2034 | { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat, "v62,v65,v66" }, |
2035 | { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_128B, "v62,v65,v66" }, |
2036 | { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_dv, "v62,v65,v66" }, |
2037 | { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_dv_128B, "v62,v65,v66" }, |
2038 | { Hexagon::BI__builtin_HEXAGON_V6_vaddw, "v60,v62,v65,v66" }, |
2039 | { Hexagon::BI__builtin_HEXAGON_V6_vaddw_128B, "v60,v62,v65,v66" }, |
2040 | { Hexagon::BI__builtin_HEXAGON_V6_vaddw_dv, "v60,v62,v65,v66" }, |
2041 | { Hexagon::BI__builtin_HEXAGON_V6_vaddw_dv_128B, "v60,v62,v65,v66" }, |
2042 | { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat, "v60,v62,v65,v66" }, |
2043 | { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_128B, "v60,v62,v65,v66" }, |
2044 | { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_dv, "v60,v62,v65,v66" }, |
2045 | { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_dv_128B, "v60,v62,v65,v66" }, |
2046 | { Hexagon::BI__builtin_HEXAGON_V6_valignb, "v60,v62,v65,v66" }, |
2047 | { Hexagon::BI__builtin_HEXAGON_V6_valignb_128B, "v60,v62,v65,v66" }, |
2048 | { Hexagon::BI__builtin_HEXAGON_V6_valignbi, "v60,v62,v65,v66" }, |
2049 | { Hexagon::BI__builtin_HEXAGON_V6_valignbi_128B, "v60,v62,v65,v66" }, |
2050 | { Hexagon::BI__builtin_HEXAGON_V6_vand, "v60,v62,v65,v66" }, |
2051 | { Hexagon::BI__builtin_HEXAGON_V6_vand_128B, "v60,v62,v65,v66" }, |
2052 | { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt, "v62,v65,v66" }, |
2053 | { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_128B, "v62,v65,v66" }, |
2054 | { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_acc, "v62,v65,v66" }, |
2055 | { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_acc_128B, "v62,v65,v66" }, |
2056 | { Hexagon::BI__builtin_HEXAGON_V6_vandqrt, "v60,v62,v65,v66" }, |
2057 | { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_128B, "v60,v62,v65,v66" }, |
2058 | { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_acc, "v60,v62,v65,v66" }, |
2059 | { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_acc_128B, "v60,v62,v65,v66" }, |
2060 | { Hexagon::BI__builtin_HEXAGON_V6_vandvnqv, "v62,v65,v66" }, |
2061 | { Hexagon::BI__builtin_HEXAGON_V6_vandvnqv_128B, "v62,v65,v66" }, |
2062 | { Hexagon::BI__builtin_HEXAGON_V6_vandvqv, "v62,v65,v66" }, |
2063 | { Hexagon::BI__builtin_HEXAGON_V6_vandvqv_128B, "v62,v65,v66" }, |
2064 | { Hexagon::BI__builtin_HEXAGON_V6_vandvrt, "v60,v62,v65,v66" }, |
2065 | { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_128B, "v60,v62,v65,v66" }, |
2066 | { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_acc, "v60,v62,v65,v66" }, |
2067 | { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_acc_128B, "v60,v62,v65,v66" }, |
2068 | { Hexagon::BI__builtin_HEXAGON_V6_vaslh, "v60,v62,v65,v66" }, |
2069 | { Hexagon::BI__builtin_HEXAGON_V6_vaslh_128B, "v60,v62,v65,v66" }, |
2070 | { Hexagon::BI__builtin_HEXAGON_V6_vaslh_acc, "v65,v66" }, |
2071 | { Hexagon::BI__builtin_HEXAGON_V6_vaslh_acc_128B, "v65,v66" }, |
2072 | { Hexagon::BI__builtin_HEXAGON_V6_vaslhv, "v60,v62,v65,v66" }, |
2073 | { Hexagon::BI__builtin_HEXAGON_V6_vaslhv_128B, "v60,v62,v65,v66" }, |
2074 | { Hexagon::BI__builtin_HEXAGON_V6_vaslw, "v60,v62,v65,v66" }, |
2075 | { Hexagon::BI__builtin_HEXAGON_V6_vaslw_128B, "v60,v62,v65,v66" }, |
2076 | { Hexagon::BI__builtin_HEXAGON_V6_vaslw_acc, "v60,v62,v65,v66" }, |
2077 | { Hexagon::BI__builtin_HEXAGON_V6_vaslw_acc_128B, "v60,v62,v65,v66" }, |
2078 | { Hexagon::BI__builtin_HEXAGON_V6_vaslwv, "v60,v62,v65,v66" }, |
2079 | { Hexagon::BI__builtin_HEXAGON_V6_vaslwv_128B, "v60,v62,v65,v66" }, |
2080 | { Hexagon::BI__builtin_HEXAGON_V6_vasrh, "v60,v62,v65,v66" }, |
2081 | { Hexagon::BI__builtin_HEXAGON_V6_vasrh_128B, "v60,v62,v65,v66" }, |
2082 | { Hexagon::BI__builtin_HEXAGON_V6_vasrh_acc, "v65,v66" }, |
2083 | { Hexagon::BI__builtin_HEXAGON_V6_vasrh_acc_128B, "v65,v66" }, |
2084 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhbrndsat, "v60,v62,v65,v66" }, |
2085 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhbrndsat_128B, "v60,v62,v65,v66" }, |
2086 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhbsat, "v62,v65,v66" }, |
2087 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhbsat_128B, "v62,v65,v66" }, |
2088 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhubrndsat, "v60,v62,v65,v66" }, |
2089 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhubrndsat_128B, "v60,v62,v65,v66" }, |
2090 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhubsat, "v60,v62,v65,v66" }, |
2091 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhubsat_128B, "v60,v62,v65,v66" }, |
2092 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhv, "v60,v62,v65,v66" }, |
2093 | { Hexagon::BI__builtin_HEXAGON_V6_vasrhv_128B, "v60,v62,v65,v66" }, |
2094 | { Hexagon::BI__builtin_HEXAGON_V6_vasr_into, "v66" }, |
2095 | { Hexagon::BI__builtin_HEXAGON_V6_vasr_into_128B, "v66" }, |
2096 | { Hexagon::BI__builtin_HEXAGON_V6_vasruhubrndsat, "v65,v66" }, |
2097 | { Hexagon::BI__builtin_HEXAGON_V6_vasruhubrndsat_128B, "v65,v66" }, |
2098 | { Hexagon::BI__builtin_HEXAGON_V6_vasruhubsat, "v65,v66" }, |
2099 | { Hexagon::BI__builtin_HEXAGON_V6_vasruhubsat_128B, "v65,v66" }, |
2100 | { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhrndsat, "v62,v65,v66" }, |
2101 | { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhrndsat_128B, "v62,v65,v66" }, |
2102 | { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhsat, "v65,v66" }, |
2103 | { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhsat_128B, "v65,v66" }, |
2104 | { Hexagon::BI__builtin_HEXAGON_V6_vasrw, "v60,v62,v65,v66" }, |
2105 | { Hexagon::BI__builtin_HEXAGON_V6_vasrw_128B, "v60,v62,v65,v66" }, |
2106 | { Hexagon::BI__builtin_HEXAGON_V6_vasrw_acc, "v60,v62,v65,v66" }, |
2107 | { Hexagon::BI__builtin_HEXAGON_V6_vasrw_acc_128B, "v60,v62,v65,v66" }, |
2108 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwh, "v60,v62,v65,v66" }, |
2109 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwh_128B, "v60,v62,v65,v66" }, |
2110 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwhrndsat, "v60,v62,v65,v66" }, |
2111 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwhrndsat_128B, "v60,v62,v65,v66" }, |
2112 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwhsat, "v60,v62,v65,v66" }, |
2113 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwhsat_128B, "v60,v62,v65,v66" }, |
2114 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhrndsat, "v62,v65,v66" }, |
2115 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhrndsat_128B, "v62,v65,v66" }, |
2116 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhsat, "v60,v62,v65,v66" }, |
2117 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhsat_128B, "v60,v62,v65,v66" }, |
2118 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwv, "v60,v62,v65,v66" }, |
2119 | { Hexagon::BI__builtin_HEXAGON_V6_vasrwv_128B, "v60,v62,v65,v66" }, |
2120 | { Hexagon::BI__builtin_HEXAGON_V6_vassign, "v60,v62,v65,v66" }, |
2121 | { Hexagon::BI__builtin_HEXAGON_V6_vassign_128B, "v60,v62,v65,v66" }, |
2122 | { Hexagon::BI__builtin_HEXAGON_V6_vassignp, "v60,v62,v65,v66" }, |
2123 | { Hexagon::BI__builtin_HEXAGON_V6_vassignp_128B, "v60,v62,v65,v66" }, |
2124 | { Hexagon::BI__builtin_HEXAGON_V6_vavgb, "v65,v66" }, |
2125 | { Hexagon::BI__builtin_HEXAGON_V6_vavgb_128B, "v65,v66" }, |
2126 | { Hexagon::BI__builtin_HEXAGON_V6_vavgbrnd, "v65,v66" }, |
2127 | { Hexagon::BI__builtin_HEXAGON_V6_vavgbrnd_128B, "v65,v66" }, |
2128 | { Hexagon::BI__builtin_HEXAGON_V6_vavgh, "v60,v62,v65,v66" }, |
2129 | { Hexagon::BI__builtin_HEXAGON_V6_vavgh_128B, "v60,v62,v65,v66" }, |
2130 | { Hexagon::BI__builtin_HEXAGON_V6_vavghrnd, "v60,v62,v65,v66" }, |
2131 | { Hexagon::BI__builtin_HEXAGON_V6_vavghrnd_128B, "v60,v62,v65,v66" }, |
2132 | { Hexagon::BI__builtin_HEXAGON_V6_vavgub, "v60,v62,v65,v66" }, |
2133 | { Hexagon::BI__builtin_HEXAGON_V6_vavgub_128B, "v60,v62,v65,v66" }, |
2134 | { Hexagon::BI__builtin_HEXAGON_V6_vavgubrnd, "v60,v62,v65,v66" }, |
2135 | { Hexagon::BI__builtin_HEXAGON_V6_vavgubrnd_128B, "v60,v62,v65,v66" }, |
2136 | { Hexagon::BI__builtin_HEXAGON_V6_vavguh, "v60,v62,v65,v66" }, |
2137 | { Hexagon::BI__builtin_HEXAGON_V6_vavguh_128B, "v60,v62,v65,v66" }, |
2138 | { Hexagon::BI__builtin_HEXAGON_V6_vavguhrnd, "v60,v62,v65,v66" }, |
2139 | { Hexagon::BI__builtin_HEXAGON_V6_vavguhrnd_128B, "v60,v62,v65,v66" }, |
2140 | { Hexagon::BI__builtin_HEXAGON_V6_vavguw, "v65,v66" }, |
2141 | { Hexagon::BI__builtin_HEXAGON_V6_vavguw_128B, "v65,v66" }, |
2142 | { Hexagon::BI__builtin_HEXAGON_V6_vavguwrnd, "v65,v66" }, |
2143 | { Hexagon::BI__builtin_HEXAGON_V6_vavguwrnd_128B, "v65,v66" }, |
2144 | { Hexagon::BI__builtin_HEXAGON_V6_vavgw, "v60,v62,v65,v66" }, |
2145 | { Hexagon::BI__builtin_HEXAGON_V6_vavgw_128B, "v60,v62,v65,v66" }, |
2146 | { Hexagon::BI__builtin_HEXAGON_V6_vavgwrnd, "v60,v62,v65,v66" }, |
2147 | { Hexagon::BI__builtin_HEXAGON_V6_vavgwrnd_128B, "v60,v62,v65,v66" }, |
2148 | { Hexagon::BI__builtin_HEXAGON_V6_vcl0h, "v60,v62,v65,v66" }, |
2149 | { Hexagon::BI__builtin_HEXAGON_V6_vcl0h_128B, "v60,v62,v65,v66" }, |
2150 | { Hexagon::BI__builtin_HEXAGON_V6_vcl0w, "v60,v62,v65,v66" }, |
2151 | { Hexagon::BI__builtin_HEXAGON_V6_vcl0w_128B, "v60,v62,v65,v66" }, |
2152 | { Hexagon::BI__builtin_HEXAGON_V6_vcombine, "v60,v62,v65,v66" }, |
2153 | { Hexagon::BI__builtin_HEXAGON_V6_vcombine_128B, "v60,v62,v65,v66" }, |
2154 | { Hexagon::BI__builtin_HEXAGON_V6_vd0, "v60,v62,v65,v66" }, |
2155 | { Hexagon::BI__builtin_HEXAGON_V6_vd0_128B, "v60,v62,v65,v66" }, |
2156 | { Hexagon::BI__builtin_HEXAGON_V6_vdd0, "v65,v66" }, |
2157 | { Hexagon::BI__builtin_HEXAGON_V6_vdd0_128B, "v65,v66" }, |
2158 | { Hexagon::BI__builtin_HEXAGON_V6_vdealb, "v60,v62,v65,v66" }, |
2159 | { Hexagon::BI__builtin_HEXAGON_V6_vdealb_128B, "v60,v62,v65,v66" }, |
2160 | { Hexagon::BI__builtin_HEXAGON_V6_vdealb4w, "v60,v62,v65,v66" }, |
2161 | { Hexagon::BI__builtin_HEXAGON_V6_vdealb4w_128B, "v60,v62,v65,v66" }, |
2162 | { Hexagon::BI__builtin_HEXAGON_V6_vdealh, "v60,v62,v65,v66" }, |
2163 | { Hexagon::BI__builtin_HEXAGON_V6_vdealh_128B, "v60,v62,v65,v66" }, |
2164 | { Hexagon::BI__builtin_HEXAGON_V6_vdealvdd, "v60,v62,v65,v66" }, |
2165 | { Hexagon::BI__builtin_HEXAGON_V6_vdealvdd_128B, "v60,v62,v65,v66" }, |
2166 | { Hexagon::BI__builtin_HEXAGON_V6_vdelta, "v60,v62,v65,v66" }, |
2167 | { Hexagon::BI__builtin_HEXAGON_V6_vdelta_128B, "v60,v62,v65,v66" }, |
2168 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus, "v60,v62,v65,v66" }, |
2169 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_128B, "v60,v62,v65,v66" }, |
2170 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_acc, "v60,v62,v65,v66" }, |
2171 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_acc_128B, "v60,v62,v65,v66" }, |
2172 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv, "v60,v62,v65,v66" }, |
2173 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_128B, "v60,v62,v65,v66" }, |
2174 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_acc, "v60,v62,v65,v66" }, |
2175 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B, "v60,v62,v65,v66" }, |
2176 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb, "v60,v62,v65,v66" }, |
2177 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_128B, "v60,v62,v65,v66" }, |
2178 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_acc, "v60,v62,v65,v66" }, |
2179 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_acc_128B, "v60,v62,v65,v66" }, |
2180 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv, "v60,v62,v65,v66" }, |
2181 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_128B, "v60,v62,v65,v66" }, |
2182 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_acc, "v60,v62,v65,v66" }, |
2183 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B, "v60,v62,v65,v66" }, |
2184 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat, "v60,v62,v65,v66" }, |
2185 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_128B, "v60,v62,v65,v66" }, |
2186 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_acc, "v60,v62,v65,v66" }, |
2187 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_acc_128B, "v60,v62,v65,v66" }, |
2188 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat, "v60,v62,v65,v66" }, |
2189 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_128B, "v60,v62,v65,v66" }, |
2190 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_acc, "v60,v62,v65,v66" }, |
2191 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_acc_128B, "v60,v62,v65,v66" }, |
2192 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat, "v60,v62,v65,v66" }, |
2193 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_128B, "v60,v62,v65,v66" }, |
2194 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_acc, "v60,v62,v65,v66" }, |
2195 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B, "v60,v62,v65,v66" }, |
2196 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat, "v60,v62,v65,v66" }, |
2197 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_128B, "v60,v62,v65,v66" }, |
2198 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_acc, "v60,v62,v65,v66" }, |
2199 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B, "v60,v62,v65,v66" }, |
2200 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat, "v60,v62,v65,v66" }, |
2201 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_128B, "v60,v62,v65,v66" }, |
2202 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_acc, "v60,v62,v65,v66" }, |
2203 | { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B, "v60,v62,v65,v66" }, |
2204 | { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh, "v60,v62,v65,v66" }, |
2205 | { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_128B, "v60,v62,v65,v66" }, |
2206 | { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_acc, "v60,v62,v65,v66" }, |
2207 | { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_acc_128B, "v60,v62,v65,v66" }, |
2208 | { Hexagon::BI__builtin_HEXAGON_V6_veqb, "v60,v62,v65,v66" }, |
2209 | { Hexagon::BI__builtin_HEXAGON_V6_veqb_128B, "v60,v62,v65,v66" }, |
2210 | { Hexagon::BI__builtin_HEXAGON_V6_veqb_and, "v60,v62,v65,v66" }, |
2211 | { Hexagon::BI__builtin_HEXAGON_V6_veqb_and_128B, "v60,v62,v65,v66" }, |
2212 | { Hexagon::BI__builtin_HEXAGON_V6_veqb_or, "v60,v62,v65,v66" }, |
2213 | { Hexagon::BI__builtin_HEXAGON_V6_veqb_or_128B, "v60,v62,v65,v66" }, |
2214 | { Hexagon::BI__builtin_HEXAGON_V6_veqb_xor, "v60,v62,v65,v66" }, |
2215 | { Hexagon::BI__builtin_HEXAGON_V6_veqb_xor_128B, "v60,v62,v65,v66" }, |
2216 | { Hexagon::BI__builtin_HEXAGON_V6_veqh, "v60,v62,v65,v66" }, |
2217 | { Hexagon::BI__builtin_HEXAGON_V6_veqh_128B, "v60,v62,v65,v66" }, |
2218 | { Hexagon::BI__builtin_HEXAGON_V6_veqh_and, "v60,v62,v65,v66" }, |
2219 | { Hexagon::BI__builtin_HEXAGON_V6_veqh_and_128B, "v60,v62,v65,v66" }, |
2220 | { Hexagon::BI__builtin_HEXAGON_V6_veqh_or, "v60,v62,v65,v66" }, |
2221 | { Hexagon::BI__builtin_HEXAGON_V6_veqh_or_128B, "v60,v62,v65,v66" }, |
2222 | { Hexagon::BI__builtin_HEXAGON_V6_veqh_xor, "v60,v62,v65,v66" }, |
2223 | { Hexagon::BI__builtin_HEXAGON_V6_veqh_xor_128B, "v60,v62,v65,v66" }, |
2224 | { Hexagon::BI__builtin_HEXAGON_V6_veqw, "v60,v62,v65,v66" }, |
2225 | { Hexagon::BI__builtin_HEXAGON_V6_veqw_128B, "v60,v62,v65,v66" }, |
2226 | { Hexagon::BI__builtin_HEXAGON_V6_veqw_and, "v60,v62,v65,v66" }, |
2227 | { Hexagon::BI__builtin_HEXAGON_V6_veqw_and_128B, "v60,v62,v65,v66" }, |
2228 | { Hexagon::BI__builtin_HEXAGON_V6_veqw_or, "v60,v62,v65,v66" }, |
2229 | { Hexagon::BI__builtin_HEXAGON_V6_veqw_or_128B, "v60,v62,v65,v66" }, |
2230 | { Hexagon::BI__builtin_HEXAGON_V6_veqw_xor, "v60,v62,v65,v66" }, |
2231 | { Hexagon::BI__builtin_HEXAGON_V6_veqw_xor_128B, "v60,v62,v65,v66" }, |
2232 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb, "v60,v62,v65,v66" }, |
2233 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb_128B, "v60,v62,v65,v66" }, |
2234 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb_and, "v60,v62,v65,v66" }, |
2235 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb_and_128B, "v60,v62,v65,v66" }, |
2236 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb_or, "v60,v62,v65,v66" }, |
2237 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb_or_128B, "v60,v62,v65,v66" }, |
2238 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb_xor, "v60,v62,v65,v66" }, |
2239 | { Hexagon::BI__builtin_HEXAGON_V6_vgtb_xor_128B, "v60,v62,v65,v66" }, |
2240 | { Hexagon::BI__builtin_HEXAGON_V6_vgth, "v60,v62,v65,v66" }, |
2241 | { Hexagon::BI__builtin_HEXAGON_V6_vgth_128B, "v60,v62,v65,v66" }, |
2242 | { Hexagon::BI__builtin_HEXAGON_V6_vgth_and, "v60,v62,v65,v66" }, |
2243 | { Hexagon::BI__builtin_HEXAGON_V6_vgth_and_128B, "v60,v62,v65,v66" }, |
2244 | { Hexagon::BI__builtin_HEXAGON_V6_vgth_or, "v60,v62,v65,v66" }, |
2245 | { Hexagon::BI__builtin_HEXAGON_V6_vgth_or_128B, "v60,v62,v65,v66" }, |
2246 | { Hexagon::BI__builtin_HEXAGON_V6_vgth_xor, "v60,v62,v65,v66" }, |
2247 | { Hexagon::BI__builtin_HEXAGON_V6_vgth_xor_128B, "v60,v62,v65,v66" }, |
2248 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub, "v60,v62,v65,v66" }, |
2249 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub_128B, "v60,v62,v65,v66" }, |
2250 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub_and, "v60,v62,v65,v66" }, |
2251 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub_and_128B, "v60,v62,v65,v66" }, |
2252 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub_or, "v60,v62,v65,v66" }, |
2253 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub_or_128B, "v60,v62,v65,v66" }, |
2254 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub_xor, "v60,v62,v65,v66" }, |
2255 | { Hexagon::BI__builtin_HEXAGON_V6_vgtub_xor_128B, "v60,v62,v65,v66" }, |
2256 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh, "v60,v62,v65,v66" }, |
2257 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_128B, "v60,v62,v65,v66" }, |
2258 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_and, "v60,v62,v65,v66" }, |
2259 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_and_128B, "v60,v62,v65,v66" }, |
2260 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_or, "v60,v62,v65,v66" }, |
2261 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_or_128B, "v60,v62,v65,v66" }, |
2262 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_xor, "v60,v62,v65,v66" }, |
2263 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_xor_128B, "v60,v62,v65,v66" }, |
2264 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw, "v60,v62,v65,v66" }, |
2265 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_128B, "v60,v62,v65,v66" }, |
2266 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_and, "v60,v62,v65,v66" }, |
2267 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_and_128B, "v60,v62,v65,v66" }, |
2268 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_or, "v60,v62,v65,v66" }, |
2269 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_or_128B, "v60,v62,v65,v66" }, |
2270 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_xor, "v60,v62,v65,v66" }, |
2271 | { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_xor_128B, "v60,v62,v65,v66" }, |
2272 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw, "v60,v62,v65,v66" }, |
2273 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw_128B, "v60,v62,v65,v66" }, |
2274 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw_and, "v60,v62,v65,v66" }, |
2275 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw_and_128B, "v60,v62,v65,v66" }, |
2276 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw_or, "v60,v62,v65,v66" }, |
2277 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw_or_128B, "v60,v62,v65,v66" }, |
2278 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw_xor, "v60,v62,v65,v66" }, |
2279 | { Hexagon::BI__builtin_HEXAGON_V6_vgtw_xor_128B, "v60,v62,v65,v66" }, |
2280 | { Hexagon::BI__builtin_HEXAGON_V6_vinsertwr, "v60,v62,v65,v66" }, |
2281 | { Hexagon::BI__builtin_HEXAGON_V6_vinsertwr_128B, "v60,v62,v65,v66" }, |
2282 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignb, "v60,v62,v65,v66" }, |
2283 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignb_128B, "v60,v62,v65,v66" }, |
2284 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi, "v60,v62,v65,v66" }, |
2285 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi_128B, "v60,v62,v65,v66" }, |
2286 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrb, "v62,v65,v66" }, |
2287 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrb_128B, "v62,v65,v66" }, |
2288 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrh, "v60,v62,v65,v66" }, |
2289 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrh_128B, "v60,v62,v65,v66" }, |
2290 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrhv, "v60,v62,v65,v66" }, |
2291 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrhv_128B, "v60,v62,v65,v66" }, |
2292 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrw, "v60,v62,v65,v66" }, |
2293 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrw_128B, "v60,v62,v65,v66" }, |
2294 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrwv, "v60,v62,v65,v66" }, |
2295 | { Hexagon::BI__builtin_HEXAGON_V6_vlsrwv_128B, "v60,v62,v65,v66" }, |
2296 | { Hexagon::BI__builtin_HEXAGON_V6_vlut4, "v65,v66" }, |
2297 | { Hexagon::BI__builtin_HEXAGON_V6_vlut4_128B, "v65,v66" }, |
2298 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb, "v60,v62,v65,v66" }, |
2299 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_128B, "v60,v62,v65,v66" }, |
2300 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi, "v62,v65,v66" }, |
2301 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi_128B, "v62,v65,v66" }, |
2302 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_nm, "v62,v65,v66" }, |
2303 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_nm_128B, "v62,v65,v66" }, |
2304 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracc, "v60,v62,v65,v66" }, |
2305 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracc_128B, "v60,v62,v65,v66" }, |
2306 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci, "v62,v65,v66" }, |
2307 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci_128B, "v62,v65,v66" }, |
2308 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh, "v60,v62,v65,v66" }, |
2309 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_128B, "v60,v62,v65,v66" }, |
2310 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi, "v62,v65,v66" }, |
2311 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi_128B, "v62,v65,v66" }, |
2312 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_nm, "v62,v65,v66" }, |
2313 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_nm_128B, "v62,v65,v66" }, |
2314 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracc, "v60,v62,v65,v66" }, |
2315 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracc_128B, "v60,v62,v65,v66" }, |
2316 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci, "v62,v65,v66" }, |
2317 | { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci_128B, "v62,v65,v66" }, |
2318 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxb, "v62,v65,v66" }, |
2319 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxb_128B, "v62,v65,v66" }, |
2320 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxh, "v60,v62,v65,v66" }, |
2321 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxh_128B, "v60,v62,v65,v66" }, |
2322 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxub, "v60,v62,v65,v66" }, |
2323 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxub_128B, "v60,v62,v65,v66" }, |
2324 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxuh, "v60,v62,v65,v66" }, |
2325 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxuh_128B, "v60,v62,v65,v66" }, |
2326 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxw, "v60,v62,v65,v66" }, |
2327 | { Hexagon::BI__builtin_HEXAGON_V6_vmaxw_128B, "v60,v62,v65,v66" }, |
2328 | { Hexagon::BI__builtin_HEXAGON_V6_vminb, "v62,v65,v66" }, |
2329 | { Hexagon::BI__builtin_HEXAGON_V6_vminb_128B, "v62,v65,v66" }, |
2330 | { Hexagon::BI__builtin_HEXAGON_V6_vminh, "v60,v62,v65,v66" }, |
2331 | { Hexagon::BI__builtin_HEXAGON_V6_vminh_128B, "v60,v62,v65,v66" }, |
2332 | { Hexagon::BI__builtin_HEXAGON_V6_vminub, "v60,v62,v65,v66" }, |
2333 | { Hexagon::BI__builtin_HEXAGON_V6_vminub_128B, "v60,v62,v65,v66" }, |
2334 | { Hexagon::BI__builtin_HEXAGON_V6_vminuh, "v60,v62,v65,v66" }, |
2335 | { Hexagon::BI__builtin_HEXAGON_V6_vminuh_128B, "v60,v62,v65,v66" }, |
2336 | { Hexagon::BI__builtin_HEXAGON_V6_vminw, "v60,v62,v65,v66" }, |
2337 | { Hexagon::BI__builtin_HEXAGON_V6_vminw_128B, "v60,v62,v65,v66" }, |
2338 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabus, "v60,v62,v65,v66" }, |
2339 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_128B, "v60,v62,v65,v66" }, |
2340 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_acc, "v60,v62,v65,v66" }, |
2341 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_acc_128B, "v60,v62,v65,v66" }, |
2342 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabusv, "v60,v62,v65,v66" }, |
2343 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabusv_128B, "v60,v62,v65,v66" }, |
2344 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu, "v65,v66" }, |
2345 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_128B, "v65,v66" }, |
2346 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_acc, "v65,v66" }, |
2347 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_acc_128B, "v65,v66" }, |
2348 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabuuv, "v60,v62,v65,v66" }, |
2349 | { Hexagon::BI__builtin_HEXAGON_V6_vmpabuuv_128B, "v60,v62,v65,v66" }, |
2350 | { Hexagon::BI__builtin_HEXAGON_V6_vmpahb, "v60,v62,v65,v66" }, |
2351 | { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_128B, "v60,v62,v65,v66" }, |
2352 | { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_acc, "v60,v62,v65,v66" }, |
2353 | { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_acc_128B, "v60,v62,v65,v66" }, |
2354 | { Hexagon::BI__builtin_HEXAGON_V6_vmpahhsat, "v65,v66" }, |
2355 | { Hexagon::BI__builtin_HEXAGON_V6_vmpahhsat_128B, "v65,v66" }, |
2356 | { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb, "v62,v65,v66" }, |
2357 | { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_128B, "v62,v65,v66" }, |
2358 | { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_acc, "v62,v65,v66" }, |
2359 | { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_acc_128B, "v62,v65,v66" }, |
2360 | { Hexagon::BI__builtin_HEXAGON_V6_vmpauhuhsat, "v65,v66" }, |
2361 | { Hexagon::BI__builtin_HEXAGON_V6_vmpauhuhsat_128B, "v65,v66" }, |
2362 | { Hexagon::BI__builtin_HEXAGON_V6_vmpsuhuhsat, "v65,v66" }, |
2363 | { Hexagon::BI__builtin_HEXAGON_V6_vmpsuhuhsat_128B, "v65,v66" }, |
2364 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybus, "v60,v62,v65,v66" }, |
2365 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_128B, "v60,v62,v65,v66" }, |
2366 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_acc, "v60,v62,v65,v66" }, |
2367 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_acc_128B, "v60,v62,v65,v66" }, |
2368 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv, "v60,v62,v65,v66" }, |
2369 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_128B, "v60,v62,v65,v66" }, |
2370 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_acc, "v60,v62,v65,v66" }, |
2371 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_acc_128B, "v60,v62,v65,v66" }, |
2372 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybv, "v60,v62,v65,v66" }, |
2373 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_128B, "v60,v62,v65,v66" }, |
2374 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_acc, "v60,v62,v65,v66" }, |
2375 | { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_acc_128B, "v60,v62,v65,v66" }, |
2376 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh, "v60,v62,v65,v66" }, |
2377 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_128B, "v60,v62,v65,v66" }, |
2378 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_64, "v62,v65,v66" }, |
2379 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_64_128B, "v62,v65,v66" }, |
2380 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyh, "v60,v62,v65,v66" }, |
2381 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_128B, "v60,v62,v65,v66" }, |
2382 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_acc, "v65,v66" }, |
2383 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_acc_128B, "v65,v66" }, |
2384 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsat_acc, "v60,v62,v65,v66" }, |
2385 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsat_acc_128B, "v60,v62,v65,v66" }, |
2386 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsrs, "v60,v62,v65,v66" }, |
2387 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsrs_128B, "v60,v62,v65,v66" }, |
2388 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhss, "v60,v62,v65,v66" }, |
2389 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhss_128B, "v60,v62,v65,v66" }, |
2390 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus, "v60,v62,v65,v66" }, |
2391 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_128B, "v60,v62,v65,v66" }, |
2392 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_acc, "v60,v62,v65,v66" }, |
2393 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_acc_128B, "v60,v62,v65,v66" }, |
2394 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv, "v60,v62,v65,v66" }, |
2395 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_128B, "v60,v62,v65,v66" }, |
2396 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_acc, "v60,v62,v65,v66" }, |
2397 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_acc_128B, "v60,v62,v65,v66" }, |
2398 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhvsrs, "v60,v62,v65,v66" }, |
2399 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyhvsrs_128B, "v60,v62,v65,v66" }, |
2400 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyieoh, "v60,v62,v65,v66" }, |
2401 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyieoh_128B, "v60,v62,v65,v66" }, |
2402 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewh_acc, "v60,v62,v65,v66" }, |
2403 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewh_acc_128B, "v60,v62,v65,v66" }, |
2404 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh, "v60,v62,v65,v66" }, |
2405 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_128B, "v60,v62,v65,v66" }, |
2406 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_acc, "v60,v62,v65,v66" }, |
2407 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_acc_128B, "v60,v62,v65,v66" }, |
2408 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyih, "v60,v62,v65,v66" }, |
2409 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_128B, "v60,v62,v65,v66" }, |
2410 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_acc, "v60,v62,v65,v66" }, |
2411 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_acc_128B, "v60,v62,v65,v66" }, |
2412 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb, "v60,v62,v65,v66" }, |
2413 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_128B, "v60,v62,v65,v66" }, |
2414 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_acc, "v60,v62,v65,v66" }, |
2415 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_acc_128B, "v60,v62,v65,v66" }, |
2416 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiowh, "v60,v62,v65,v66" }, |
2417 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiowh_128B, "v60,v62,v65,v66" }, |
2418 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb, "v60,v62,v65,v66" }, |
2419 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_128B, "v60,v62,v65,v66" }, |
2420 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_acc, "v60,v62,v65,v66" }, |
2421 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_acc_128B, "v60,v62,v65,v66" }, |
2422 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh, "v60,v62,v65,v66" }, |
2423 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_128B, "v60,v62,v65,v66" }, |
2424 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_acc, "v60,v62,v65,v66" }, |
2425 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_acc_128B, "v60,v62,v65,v66" }, |
2426 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub, "v62,v65,v66" }, |
2427 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_128B, "v62,v65,v66" }, |
2428 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_acc, "v62,v65,v66" }, |
2429 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_acc_128B, "v62,v65,v66" }, |
2430 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh, "v60,v62,v65,v66" }, |
2431 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_128B, "v60,v62,v65,v66" }, |
2432 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_64_acc, "v62,v65,v66" }, |
2433 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_64_acc_128B, "v62,v65,v66" }, |
2434 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd, "v60,v62,v65,v66" }, |
2435 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_128B, "v60,v62,v65,v66" }, |
2436 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_sacc, "v60,v62,v65,v66" }, |
2437 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B, "v60,v62,v65,v66" }, |
2438 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_sacc, "v60,v62,v65,v66" }, |
2439 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_sacc_128B, "v60,v62,v65,v66" }, |
2440 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyub, "v60,v62,v65,v66" }, |
2441 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_128B, "v60,v62,v65,v66" }, |
2442 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_acc, "v60,v62,v65,v66" }, |
2443 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_acc_128B, "v60,v62,v65,v66" }, |
2444 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv, "v60,v62,v65,v66" }, |
2445 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_128B, "v60,v62,v65,v66" }, |
2446 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_acc, "v60,v62,v65,v66" }, |
2447 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_acc_128B, "v60,v62,v65,v66" }, |
2448 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh, "v60,v62,v65,v66" }, |
2449 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_128B, "v60,v62,v65,v66" }, |
2450 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_acc, "v60,v62,v65,v66" }, |
2451 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_acc_128B, "v60,v62,v65,v66" }, |
2452 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe, "v65,v66" }, |
2453 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_128B, "v65,v66" }, |
2454 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_acc, "v65,v66" }, |
2455 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_acc_128B, "v65,v66" }, |
2456 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv, "v60,v62,v65,v66" }, |
2457 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_128B, "v60,v62,v65,v66" }, |
2458 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_acc, "v60,v62,v65,v66" }, |
2459 | { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_acc_128B, "v60,v62,v65,v66" }, |
2460 | { Hexagon::BI__builtin_HEXAGON_V6_vmux, "v60,v62,v65,v66" }, |
2461 | { Hexagon::BI__builtin_HEXAGON_V6_vmux_128B, "v60,v62,v65,v66" }, |
2462 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgb, "v65,v66" }, |
2463 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgb_128B, "v65,v66" }, |
2464 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgh, "v60,v62,v65,v66" }, |
2465 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgh_128B, "v60,v62,v65,v66" }, |
2466 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgub, "v60,v62,v65,v66" }, |
2467 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgub_128B, "v60,v62,v65,v66" }, |
2468 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgw, "v60,v62,v65,v66" }, |
2469 | { Hexagon::BI__builtin_HEXAGON_V6_vnavgw_128B, "v60,v62,v65,v66" }, |
2470 | { Hexagon::BI__builtin_HEXAGON_V6_vnormamth, "v60,v62,v65,v66" }, |
2471 | { Hexagon::BI__builtin_HEXAGON_V6_vnormamth_128B, "v60,v62,v65,v66" }, |
2472 | { Hexagon::BI__builtin_HEXAGON_V6_vnormamtw, "v60,v62,v65,v66" }, |
2473 | { Hexagon::BI__builtin_HEXAGON_V6_vnormamtw_128B, "v60,v62,v65,v66" }, |
2474 | { Hexagon::BI__builtin_HEXAGON_V6_vnot, "v60,v62,v65,v66" }, |
2475 | { Hexagon::BI__builtin_HEXAGON_V6_vnot_128B, "v60,v62,v65,v66" }, |
2476 | { Hexagon::BI__builtin_HEXAGON_V6_vor, "v60,v62,v65,v66" }, |
2477 | { Hexagon::BI__builtin_HEXAGON_V6_vor_128B, "v60,v62,v65,v66" }, |
2478 | { Hexagon::BI__builtin_HEXAGON_V6_vpackeb, "v60,v62,v65,v66" }, |
2479 | { Hexagon::BI__builtin_HEXAGON_V6_vpackeb_128B, "v60,v62,v65,v66" }, |
2480 | { Hexagon::BI__builtin_HEXAGON_V6_vpackeh, "v60,v62,v65,v66" }, |
2481 | { Hexagon::BI__builtin_HEXAGON_V6_vpackeh_128B, "v60,v62,v65,v66" }, |
2482 | { Hexagon::BI__builtin_HEXAGON_V6_vpackhb_sat, "v60,v62,v65,v66" }, |
2483 | { Hexagon::BI__builtin_HEXAGON_V6_vpackhb_sat_128B, "v60,v62,v65,v66" }, |
2484 | { Hexagon::BI__builtin_HEXAGON_V6_vpackhub_sat, "v60,v62,v65,v66" }, |
2485 | { Hexagon::BI__builtin_HEXAGON_V6_vpackhub_sat_128B, "v60,v62,v65,v66" }, |
2486 | { Hexagon::BI__builtin_HEXAGON_V6_vpackob, "v60,v62,v65,v66" }, |
2487 | { Hexagon::BI__builtin_HEXAGON_V6_vpackob_128B, "v60,v62,v65,v66" }, |
2488 | { Hexagon::BI__builtin_HEXAGON_V6_vpackoh, "v60,v62,v65,v66" }, |
2489 | { Hexagon::BI__builtin_HEXAGON_V6_vpackoh_128B, "v60,v62,v65,v66" }, |
2490 | { Hexagon::BI__builtin_HEXAGON_V6_vpackwh_sat, "v60,v62,v65,v66" }, |
2491 | { Hexagon::BI__builtin_HEXAGON_V6_vpackwh_sat_128B, "v60,v62,v65,v66" }, |
2492 | { Hexagon::BI__builtin_HEXAGON_V6_vpackwuh_sat, "v60,v62,v65,v66" }, |
2493 | { Hexagon::BI__builtin_HEXAGON_V6_vpackwuh_sat_128B, "v60,v62,v65,v66" }, |
2494 | { Hexagon::BI__builtin_HEXAGON_V6_vpopcounth, "v60,v62,v65,v66" }, |
2495 | { Hexagon::BI__builtin_HEXAGON_V6_vpopcounth_128B, "v60,v62,v65,v66" }, |
2496 | { Hexagon::BI__builtin_HEXAGON_V6_vprefixqb, "v65,v66" }, |
2497 | { Hexagon::BI__builtin_HEXAGON_V6_vprefixqb_128B, "v65,v66" }, |
2498 | { Hexagon::BI__builtin_HEXAGON_V6_vprefixqh, "v65,v66" }, |
2499 | { Hexagon::BI__builtin_HEXAGON_V6_vprefixqh_128B, "v65,v66" }, |
2500 | { Hexagon::BI__builtin_HEXAGON_V6_vprefixqw, "v65,v66" }, |
2501 | { Hexagon::BI__builtin_HEXAGON_V6_vprefixqw_128B, "v65,v66" }, |
2502 | { Hexagon::BI__builtin_HEXAGON_V6_vrdelta, "v60,v62,v65,v66" }, |
2503 | { Hexagon::BI__builtin_HEXAGON_V6_vrdelta_128B, "v60,v62,v65,v66" }, |
2504 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt, "v65" }, |
2505 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_128B, "v65" }, |
2506 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_acc, "v65" }, |
2507 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B, "v65" }, |
2508 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus, "v60,v62,v65,v66" }, |
2509 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_128B, "v60,v62,v65,v66" }, |
2510 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_acc, "v60,v62,v65,v66" }, |
2511 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_acc_128B, "v60,v62,v65,v66" }, |
2512 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi, "v60,v62,v65,v66" }, |
2513 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_128B, "v60,v62,v65,v66" }, |
2514 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc, "v60,v62,v65,v66" }, |
2515 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc_128B, "v60,v62,v65,v66" }, |
2516 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv, "v60,v62,v65,v66" }, |
2517 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_128B, "v60,v62,v65,v66" }, |
2518 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_acc, "v60,v62,v65,v66" }, |
2519 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_acc_128B, "v60,v62,v65,v66" }, |
2520 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv, "v60,v62,v65,v66" }, |
2521 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_128B, "v60,v62,v65,v66" }, |
2522 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_acc, "v60,v62,v65,v66" }, |
2523 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_acc_128B, "v60,v62,v65,v66" }, |
2524 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub, "v60,v62,v65,v66" }, |
2525 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_128B, "v60,v62,v65,v66" }, |
2526 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_acc, "v60,v62,v65,v66" }, |
2527 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_acc_128B, "v60,v62,v65,v66" }, |
2528 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi, "v60,v62,v65,v66" }, |
2529 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_128B, "v60,v62,v65,v66" }, |
2530 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc, "v60,v62,v65,v66" }, |
2531 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc_128B, "v60,v62,v65,v66" }, |
2532 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt, "v65" }, |
2533 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_128B, "v65" }, |
2534 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_acc, "v65" }, |
2535 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B, "v65" }, |
2536 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv, "v60,v62,v65,v66" }, |
2537 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_128B, "v60,v62,v65,v66" }, |
2538 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_acc, "v60,v62,v65,v66" }, |
2539 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_acc_128B, "v60,v62,v65,v66" }, |
2540 | { Hexagon::BI__builtin_HEXAGON_V6_vror, "v60,v62,v65,v66" }, |
2541 | { Hexagon::BI__builtin_HEXAGON_V6_vror_128B, "v60,v62,v65,v66" }, |
2542 | { Hexagon::BI__builtin_HEXAGON_V6_vrotr, "v66" }, |
2543 | { Hexagon::BI__builtin_HEXAGON_V6_vrotr_128B, "v66" }, |
2544 | { Hexagon::BI__builtin_HEXAGON_V6_vroundhb, "v60,v62,v65,v66" }, |
2545 | { Hexagon::BI__builtin_HEXAGON_V6_vroundhb_128B, "v60,v62,v65,v66" }, |
2546 | { Hexagon::BI__builtin_HEXAGON_V6_vroundhub, "v60,v62,v65,v66" }, |
2547 | { Hexagon::BI__builtin_HEXAGON_V6_vroundhub_128B, "v60,v62,v65,v66" }, |
2548 | { Hexagon::BI__builtin_HEXAGON_V6_vrounduhub, "v62,v65,v66" }, |
2549 | { Hexagon::BI__builtin_HEXAGON_V6_vrounduhub_128B, "v62,v65,v66" }, |
2550 | { Hexagon::BI__builtin_HEXAGON_V6_vrounduwuh, "v62,v65,v66" }, |
2551 | { Hexagon::BI__builtin_HEXAGON_V6_vrounduwuh_128B, "v62,v65,v66" }, |
2552 | { Hexagon::BI__builtin_HEXAGON_V6_vroundwh, "v60,v62,v65,v66" }, |
2553 | { Hexagon::BI__builtin_HEXAGON_V6_vroundwh_128B, "v60,v62,v65,v66" }, |
2554 | { Hexagon::BI__builtin_HEXAGON_V6_vroundwuh, "v60,v62,v65,v66" }, |
2555 | { Hexagon::BI__builtin_HEXAGON_V6_vroundwuh_128B, "v60,v62,v65,v66" }, |
2556 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi, "v60,v62,v65,v66" }, |
2557 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_128B, "v60,v62,v65,v66" }, |
2558 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc, "v60,v62,v65,v66" }, |
2559 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc_128B, "v60,v62,v65,v66" }, |
2560 | { Hexagon::BI__builtin_HEXAGON_V6_vsatdw, "v66" }, |
2561 | { Hexagon::BI__builtin_HEXAGON_V6_vsatdw_128B, "v66" }, |
2562 | { Hexagon::BI__builtin_HEXAGON_V6_vsathub, "v60,v62,v65,v66" }, |
2563 | { Hexagon::BI__builtin_HEXAGON_V6_vsathub_128B, "v60,v62,v65,v66" }, |
2564 | { Hexagon::BI__builtin_HEXAGON_V6_vsatuwuh, "v62,v65,v66" }, |
2565 | { Hexagon::BI__builtin_HEXAGON_V6_vsatuwuh_128B, "v62,v65,v66" }, |
2566 | { Hexagon::BI__builtin_HEXAGON_V6_vsatwh, "v60,v62,v65,v66" }, |
2567 | { Hexagon::BI__builtin_HEXAGON_V6_vsatwh_128B, "v60,v62,v65,v66" }, |
2568 | { Hexagon::BI__builtin_HEXAGON_V6_vsb, "v60,v62,v65,v66" }, |
2569 | { Hexagon::BI__builtin_HEXAGON_V6_vsb_128B, "v60,v62,v65,v66" }, |
2570 | { Hexagon::BI__builtin_HEXAGON_V6_vsh, "v60,v62,v65,v66" }, |
2571 | { Hexagon::BI__builtin_HEXAGON_V6_vsh_128B, "v60,v62,v65,v66" }, |
2572 | { Hexagon::BI__builtin_HEXAGON_V6_vshufeh, "v60,v62,v65,v66" }, |
2573 | { Hexagon::BI__builtin_HEXAGON_V6_vshufeh_128B, "v60,v62,v65,v66" }, |
2574 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffb, "v60,v62,v65,v66" }, |
2575 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffb_128B, "v60,v62,v65,v66" }, |
2576 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffeb, "v60,v62,v65,v66" }, |
2577 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffeb_128B, "v60,v62,v65,v66" }, |
2578 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffh, "v60,v62,v65,v66" }, |
2579 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffh_128B, "v60,v62,v65,v66" }, |
2580 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffob, "v60,v62,v65,v66" }, |
2581 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffob_128B, "v60,v62,v65,v66" }, |
2582 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffvdd, "v60,v62,v65,v66" }, |
2583 | { Hexagon::BI__builtin_HEXAGON_V6_vshuffvdd_128B, "v60,v62,v65,v66" }, |
2584 | { Hexagon::BI__builtin_HEXAGON_V6_vshufoeb, "v60,v62,v65,v66" }, |
2585 | { Hexagon::BI__builtin_HEXAGON_V6_vshufoeb_128B, "v60,v62,v65,v66" }, |
2586 | { Hexagon::BI__builtin_HEXAGON_V6_vshufoeh, "v60,v62,v65,v66" }, |
2587 | { Hexagon::BI__builtin_HEXAGON_V6_vshufoeh_128B, "v60,v62,v65,v66" }, |
2588 | { Hexagon::BI__builtin_HEXAGON_V6_vshufoh, "v60,v62,v65,v66" }, |
2589 | { Hexagon::BI__builtin_HEXAGON_V6_vshufoh_128B, "v60,v62,v65,v66" }, |
2590 | { Hexagon::BI__builtin_HEXAGON_V6_vsubb, "v60,v62,v65,v66" }, |
2591 | { Hexagon::BI__builtin_HEXAGON_V6_vsubb_128B, "v60,v62,v65,v66" }, |
2592 | { Hexagon::BI__builtin_HEXAGON_V6_vsubb_dv, "v60,v62,v65,v66" }, |
2593 | { Hexagon::BI__builtin_HEXAGON_V6_vsubb_dv_128B, "v60,v62,v65,v66" }, |
2594 | { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat, "v62,v65,v66" }, |
2595 | { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_128B, "v62,v65,v66" }, |
2596 | { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_dv, "v62,v65,v66" }, |
2597 | { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_dv_128B, "v62,v65,v66" }, |
2598 | { Hexagon::BI__builtin_HEXAGON_V6_vsubcarry, "v62,v65,v66" }, |
2599 | { Hexagon::BI__builtin_HEXAGON_V6_vsubcarry_128B, "v62,v65,v66" }, |
2600 | { Hexagon::BI__builtin_HEXAGON_V6_vsubh, "v60,v62,v65,v66" }, |
2601 | { Hexagon::BI__builtin_HEXAGON_V6_vsubh_128B, "v60,v62,v65,v66" }, |
2602 | { Hexagon::BI__builtin_HEXAGON_V6_vsubh_dv, "v60,v62,v65,v66" }, |
2603 | { Hexagon::BI__builtin_HEXAGON_V6_vsubh_dv_128B, "v60,v62,v65,v66" }, |
2604 | { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat, "v60,v62,v65,v66" }, |
2605 | { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_128B, "v60,v62,v65,v66" }, |
2606 | { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_dv, "v60,v62,v65,v66" }, |
2607 | { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_dv_128B, "v60,v62,v65,v66" }, |
2608 | { Hexagon::BI__builtin_HEXAGON_V6_vsubhw, "v60,v62,v65,v66" }, |
2609 | { Hexagon::BI__builtin_HEXAGON_V6_vsubhw_128B, "v60,v62,v65,v66" }, |
2610 | { Hexagon::BI__builtin_HEXAGON_V6_vsububh, "v60,v62,v65,v66" }, |
2611 | { Hexagon::BI__builtin_HEXAGON_V6_vsububh_128B, "v60,v62,v65,v66" }, |
2612 | { Hexagon::BI__builtin_HEXAGON_V6_vsububsat, "v60,v62,v65,v66" }, |
2613 | { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_128B, "v60,v62,v65,v66" }, |
2614 | { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_dv, "v60,v62,v65,v66" }, |
2615 | { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_dv_128B, "v60,v62,v65,v66" }, |
2616 | { Hexagon::BI__builtin_HEXAGON_V6_vsubububb_sat, "v62,v65,v66" }, |
2617 | { Hexagon::BI__builtin_HEXAGON_V6_vsubububb_sat_128B, "v62,v65,v66" }, |
2618 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat, "v60,v62,v65,v66" }, |
2619 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_128B, "v60,v62,v65,v66" }, |
2620 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_dv, "v60,v62,v65,v66" }, |
2621 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_dv_128B, "v60,v62,v65,v66" }, |
2622 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuhw, "v60,v62,v65,v66" }, |
2623 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuhw_128B, "v60,v62,v65,v66" }, |
2624 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat, "v62,v65,v66" }, |
2625 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_128B, "v62,v65,v66" }, |
2626 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_dv, "v62,v65,v66" }, |
2627 | { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_dv_128B, "v62,v65,v66" }, |
2628 | { Hexagon::BI__builtin_HEXAGON_V6_vsubw, "v60,v62,v65,v66" }, |
2629 | { Hexagon::BI__builtin_HEXAGON_V6_vsubw_128B, "v60,v62,v65,v66" }, |
2630 | { Hexagon::BI__builtin_HEXAGON_V6_vsubw_dv, "v60,v62,v65,v66" }, |
2631 | { Hexagon::BI__builtin_HEXAGON_V6_vsubw_dv_128B, "v60,v62,v65,v66" }, |
2632 | { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat, "v60,v62,v65,v66" }, |
2633 | { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_128B, "v60,v62,v65,v66" }, |
2634 | { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_dv, "v60,v62,v65,v66" }, |
2635 | { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_dv_128B, "v60,v62,v65,v66" }, |
2636 | { Hexagon::BI__builtin_HEXAGON_V6_vswap, "v60,v62,v65,v66" }, |
2637 | { Hexagon::BI__builtin_HEXAGON_V6_vswap_128B, "v60,v62,v65,v66" }, |
2638 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb, "v60,v62,v65,v66" }, |
2639 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_128B, "v60,v62,v65,v66" }, |
2640 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_acc, "v60,v62,v65,v66" }, |
2641 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_acc_128B, "v60,v62,v65,v66" }, |
2642 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus, "v60,v62,v65,v66" }, |
2643 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_128B, "v60,v62,v65,v66" }, |
2644 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_acc, "v60,v62,v65,v66" }, |
2645 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_acc_128B, "v60,v62,v65,v66" }, |
2646 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb, "v60,v62,v65,v66" }, |
2647 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_128B, "v60,v62,v65,v66" }, |
2648 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_acc, "v60,v62,v65,v66" }, |
2649 | { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_acc_128B, "v60,v62,v65,v66" }, |
2650 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackb, "v60,v62,v65,v66" }, |
2651 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackb_128B, "v60,v62,v65,v66" }, |
2652 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackh, "v60,v62,v65,v66" }, |
2653 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackh_128B, "v60,v62,v65,v66" }, |
2654 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackob, "v60,v62,v65,v66" }, |
2655 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackob_128B, "v60,v62,v65,v66" }, |
2656 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackoh, "v60,v62,v65,v66" }, |
2657 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackoh_128B, "v60,v62,v65,v66" }, |
2658 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackub, "v60,v62,v65,v66" }, |
2659 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackub_128B, "v60,v62,v65,v66" }, |
2660 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackuh, "v60,v62,v65,v66" }, |
2661 | { Hexagon::BI__builtin_HEXAGON_V6_vunpackuh_128B, "v60,v62,v65,v66" }, |
2662 | { Hexagon::BI__builtin_HEXAGON_V6_vxor, "v60,v62,v65,v66" }, |
2663 | { Hexagon::BI__builtin_HEXAGON_V6_vxor_128B, "v60,v62,v65,v66" }, |
2664 | { Hexagon::BI__builtin_HEXAGON_V6_vzb, "v60,v62,v65,v66" }, |
2665 | { Hexagon::BI__builtin_HEXAGON_V6_vzb_128B, "v60,v62,v65,v66" }, |
2666 | { Hexagon::BI__builtin_HEXAGON_V6_vzh, "v60,v62,v65,v66" }, |
2667 | { Hexagon::BI__builtin_HEXAGON_V6_vzh_128B, "v60,v62,v65,v66" }, |
2668 | }; |
2669 | |
2670 | |
2671 | auto SortCmp = [](const BuiltinAndString &LHS, const BuiltinAndString &RHS) { |
2672 | return LHS.BuiltinID < RHS.BuiltinID; |
2673 | }; |
2674 | static const bool SortOnce = |
2675 | (llvm::sort(ValidCPU, SortCmp), |
2676 | llvm::sort(ValidHVX, SortCmp), true); |
2677 | (void)SortOnce; |
2678 | auto LowerBoundCmp = [](const BuiltinAndString &BI, unsigned BuiltinID) { |
2679 | return BI.BuiltinID < BuiltinID; |
2680 | }; |
2681 | |
2682 | const TargetInfo &TI = Context.getTargetInfo(); |
2683 | |
2684 | const BuiltinAndString *FC = |
2685 | std::lower_bound(std::begin(ValidCPU), std::end(ValidCPU), BuiltinID, |
2686 | LowerBoundCmp); |
2687 | if (FC != std::end(ValidCPU) && FC->BuiltinID == BuiltinID) { |
2688 | const TargetOptions &Opts = TI.getTargetOpts(); |
2689 | StringRef CPU = Opts.CPU; |
2690 | if (!CPU.empty()) { |
2691 | (0) . __assert_fail ("CPU.startswith(\"hexagon\") && \"Unexpected CPU name\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 2691, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CPU.startswith("hexagon") && "Unexpected CPU name"); |
2692 | CPU.consume_front("hexagon"); |
2693 | SmallVector<StringRef, 3> CPUs; |
2694 | StringRef(FC->Str).split(CPUs, ','); |
2695 | if (llvm::none_of(CPUs, [CPU](StringRef S) { return S == CPU; })) |
2696 | return Diag(TheCall->getBeginLoc(), |
2697 | diag::err_hexagon_builtin_unsupported_cpu); |
2698 | } |
2699 | } |
2700 | |
2701 | const BuiltinAndString *FH = |
2702 | std::lower_bound(std::begin(ValidHVX), std::end(ValidHVX), BuiltinID, |
2703 | LowerBoundCmp); |
2704 | if (FH != std::end(ValidHVX) && FH->BuiltinID == BuiltinID) { |
2705 | if (!TI.hasFeature("hvx")) |
2706 | return Diag(TheCall->getBeginLoc(), |
2707 | diag::err_hexagon_builtin_requires_hvx); |
2708 | |
2709 | SmallVector<StringRef, 3> HVXs; |
2710 | StringRef(FH->Str).split(HVXs, ','); |
2711 | bool IsValid = llvm::any_of(HVXs, |
2712 | [&TI] (StringRef V) { |
2713 | std::string F = "hvx" + V.str(); |
2714 | return TI.hasFeature(F); |
2715 | }); |
2716 | if (!IsValid) |
2717 | return Diag(TheCall->getBeginLoc(), |
2718 | diag::err_hexagon_builtin_unsupported_hvx); |
2719 | } |
2720 | |
2721 | return false; |
2722 | } |
2723 | |
2724 | bool Sema::CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { |
2725 | struct ArgInfo { |
2726 | uint8_t OpNum; |
2727 | bool IsSigned; |
2728 | uint8_t BitWidth; |
2729 | uint8_t Align; |
2730 | }; |
2731 | struct BuiltinInfo { |
2732 | unsigned BuiltinID; |
2733 | ArgInfo Infos[2]; |
2734 | }; |
2735 | |
2736 | static BuiltinInfo Infos[] = { |
2737 | { Hexagon::BI__builtin_circ_ldd, {{ 3, true, 4, 3 }} }, |
2738 | { Hexagon::BI__builtin_circ_ldw, {{ 3, true, 4, 2 }} }, |
2739 | { Hexagon::BI__builtin_circ_ldh, {{ 3, true, 4, 1 }} }, |
2740 | { Hexagon::BI__builtin_circ_lduh, {{ 3, true, 4, 0 }} }, |
2741 | { Hexagon::BI__builtin_circ_ldb, {{ 3, true, 4, 0 }} }, |
2742 | { Hexagon::BI__builtin_circ_ldub, {{ 3, true, 4, 0 }} }, |
2743 | { Hexagon::BI__builtin_circ_std, {{ 3, true, 4, 3 }} }, |
2744 | { Hexagon::BI__builtin_circ_stw, {{ 3, true, 4, 2 }} }, |
2745 | { Hexagon::BI__builtin_circ_sth, {{ 3, true, 4, 1 }} }, |
2746 | { Hexagon::BI__builtin_circ_sthhi, {{ 3, true, 4, 1 }} }, |
2747 | { Hexagon::BI__builtin_circ_stb, {{ 3, true, 4, 0 }} }, |
2748 | |
2749 | { Hexagon::BI__builtin_HEXAGON_L2_loadrub_pci, {{ 1, true, 4, 0 }} }, |
2750 | { Hexagon::BI__builtin_HEXAGON_L2_loadrb_pci, {{ 1, true, 4, 0 }} }, |
2751 | { Hexagon::BI__builtin_HEXAGON_L2_loadruh_pci, {{ 1, true, 4, 1 }} }, |
2752 | { Hexagon::BI__builtin_HEXAGON_L2_loadrh_pci, {{ 1, true, 4, 1 }} }, |
2753 | { Hexagon::BI__builtin_HEXAGON_L2_loadri_pci, {{ 1, true, 4, 2 }} }, |
2754 | { Hexagon::BI__builtin_HEXAGON_L2_loadrd_pci, {{ 1, true, 4, 3 }} }, |
2755 | { Hexagon::BI__builtin_HEXAGON_S2_storerb_pci, {{ 1, true, 4, 0 }} }, |
2756 | { Hexagon::BI__builtin_HEXAGON_S2_storerh_pci, {{ 1, true, 4, 1 }} }, |
2757 | { Hexagon::BI__builtin_HEXAGON_S2_storerf_pci, {{ 1, true, 4, 1 }} }, |
2758 | { Hexagon::BI__builtin_HEXAGON_S2_storeri_pci, {{ 1, true, 4, 2 }} }, |
2759 | { Hexagon::BI__builtin_HEXAGON_S2_storerd_pci, {{ 1, true, 4, 3 }} }, |
2760 | |
2761 | { Hexagon::BI__builtin_HEXAGON_A2_combineii, {{ 1, true, 8, 0 }} }, |
2762 | { Hexagon::BI__builtin_HEXAGON_A2_tfrih, {{ 1, false, 16, 0 }} }, |
2763 | { Hexagon::BI__builtin_HEXAGON_A2_tfril, {{ 1, false, 16, 0 }} }, |
2764 | { Hexagon::BI__builtin_HEXAGON_A2_tfrpi, {{ 0, true, 8, 0 }} }, |
2765 | { Hexagon::BI__builtin_HEXAGON_A4_bitspliti, {{ 1, false, 5, 0 }} }, |
2766 | { Hexagon::BI__builtin_HEXAGON_A4_cmpbeqi, {{ 1, false, 8, 0 }} }, |
2767 | { Hexagon::BI__builtin_HEXAGON_A4_cmpbgti, {{ 1, true, 8, 0 }} }, |
2768 | { Hexagon::BI__builtin_HEXAGON_A4_cround_ri, {{ 1, false, 5, 0 }} }, |
2769 | { Hexagon::BI__builtin_HEXAGON_A4_round_ri, {{ 1, false, 5, 0 }} }, |
2770 | { Hexagon::BI__builtin_HEXAGON_A4_round_ri_sat, {{ 1, false, 5, 0 }} }, |
2771 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpbeqi, {{ 1, false, 8, 0 }} }, |
2772 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgti, {{ 1, true, 8, 0 }} }, |
2773 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpbgtui, {{ 1, false, 7, 0 }} }, |
2774 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpheqi, {{ 1, true, 8, 0 }} }, |
2775 | { Hexagon::BI__builtin_HEXAGON_A4_vcmphgti, {{ 1, true, 8, 0 }} }, |
2776 | { Hexagon::BI__builtin_HEXAGON_A4_vcmphgtui, {{ 1, false, 7, 0 }} }, |
2777 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpweqi, {{ 1, true, 8, 0 }} }, |
2778 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgti, {{ 1, true, 8, 0 }} }, |
2779 | { Hexagon::BI__builtin_HEXAGON_A4_vcmpwgtui, {{ 1, false, 7, 0 }} }, |
2780 | { Hexagon::BI__builtin_HEXAGON_C2_bitsclri, {{ 1, false, 6, 0 }} }, |
2781 | { Hexagon::BI__builtin_HEXAGON_C2_muxii, {{ 2, true, 8, 0 }} }, |
2782 | { Hexagon::BI__builtin_HEXAGON_C4_nbitsclri, {{ 1, false, 6, 0 }} }, |
2783 | { Hexagon::BI__builtin_HEXAGON_F2_dfclass, {{ 1, false, 5, 0 }} }, |
2784 | { Hexagon::BI__builtin_HEXAGON_F2_dfimm_n, {{ 0, false, 10, 0 }} }, |
2785 | { Hexagon::BI__builtin_HEXAGON_F2_dfimm_p, {{ 0, false, 10, 0 }} }, |
2786 | { Hexagon::BI__builtin_HEXAGON_F2_sfclass, {{ 1, false, 5, 0 }} }, |
2787 | { Hexagon::BI__builtin_HEXAGON_F2_sfimm_n, {{ 0, false, 10, 0 }} }, |
2788 | { Hexagon::BI__builtin_HEXAGON_F2_sfimm_p, {{ 0, false, 10, 0 }} }, |
2789 | { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addi, {{ 2, false, 6, 0 }} }, |
2790 | { Hexagon::BI__builtin_HEXAGON_M4_mpyri_addr_u2, {{ 1, false, 6, 2 }} }, |
2791 | { Hexagon::BI__builtin_HEXAGON_S2_addasl_rrri, {{ 2, false, 3, 0 }} }, |
2792 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_acc, {{ 2, false, 6, 0 }} }, |
2793 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_and, {{ 2, false, 6, 0 }} }, |
2794 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p, {{ 1, false, 6, 0 }} }, |
2795 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_nac, {{ 2, false, 6, 0 }} }, |
2796 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_or, {{ 2, false, 6, 0 }} }, |
2797 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_p_xacc, {{ 2, false, 6, 0 }} }, |
2798 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_acc, {{ 2, false, 5, 0 }} }, |
2799 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_and, {{ 2, false, 5, 0 }} }, |
2800 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r, {{ 1, false, 5, 0 }} }, |
2801 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_nac, {{ 2, false, 5, 0 }} }, |
2802 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_or, {{ 2, false, 5, 0 }} }, |
2803 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_sat, {{ 1, false, 5, 0 }} }, |
2804 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_r_xacc, {{ 2, false, 5, 0 }} }, |
2805 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vh, {{ 1, false, 4, 0 }} }, |
2806 | { Hexagon::BI__builtin_HEXAGON_S2_asl_i_vw, {{ 1, false, 5, 0 }} }, |
2807 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_acc, {{ 2, false, 6, 0 }} }, |
2808 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_and, {{ 2, false, 6, 0 }} }, |
2809 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p, {{ 1, false, 6, 0 }} }, |
2810 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_nac, {{ 2, false, 6, 0 }} }, |
2811 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_or, {{ 2, false, 6, 0 }} }, |
2812 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax, |
2813 | {{ 1, false, 6, 0 }} }, |
2814 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_p_rnd, {{ 1, false, 6, 0 }} }, |
2815 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_acc, {{ 2, false, 5, 0 }} }, |
2816 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_and, {{ 2, false, 5, 0 }} }, |
2817 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r, {{ 1, false, 5, 0 }} }, |
2818 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_nac, {{ 2, false, 5, 0 }} }, |
2819 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_or, {{ 2, false, 5, 0 }} }, |
2820 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax, |
2821 | {{ 1, false, 5, 0 }} }, |
2822 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_r_rnd, {{ 1, false, 5, 0 }} }, |
2823 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_svw_trun, {{ 1, false, 5, 0 }} }, |
2824 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vh, {{ 1, false, 4, 0 }} }, |
2825 | { Hexagon::BI__builtin_HEXAGON_S2_asr_i_vw, {{ 1, false, 5, 0 }} }, |
2826 | { Hexagon::BI__builtin_HEXAGON_S2_clrbit_i, {{ 1, false, 5, 0 }} }, |
2827 | { Hexagon::BI__builtin_HEXAGON_S2_extractu, {{ 1, false, 5, 0 }, |
2828 | { 2, false, 5, 0 }} }, |
2829 | { Hexagon::BI__builtin_HEXAGON_S2_extractup, {{ 1, false, 6, 0 }, |
2830 | { 2, false, 6, 0 }} }, |
2831 | { Hexagon::BI__builtin_HEXAGON_S2_insert, {{ 2, false, 5, 0 }, |
2832 | { 3, false, 5, 0 }} }, |
2833 | { Hexagon::BI__builtin_HEXAGON_S2_insertp, {{ 2, false, 6, 0 }, |
2834 | { 3, false, 6, 0 }} }, |
2835 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_acc, {{ 2, false, 6, 0 }} }, |
2836 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_and, {{ 2, false, 6, 0 }} }, |
2837 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p, {{ 1, false, 6, 0 }} }, |
2838 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_nac, {{ 2, false, 6, 0 }} }, |
2839 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_or, {{ 2, false, 6, 0 }} }, |
2840 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_p_xacc, {{ 2, false, 6, 0 }} }, |
2841 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_acc, {{ 2, false, 5, 0 }} }, |
2842 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_and, {{ 2, false, 5, 0 }} }, |
2843 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r, {{ 1, false, 5, 0 }} }, |
2844 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_nac, {{ 2, false, 5, 0 }} }, |
2845 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_or, {{ 2, false, 5, 0 }} }, |
2846 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_r_xacc, {{ 2, false, 5, 0 }} }, |
2847 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vh, {{ 1, false, 4, 0 }} }, |
2848 | { Hexagon::BI__builtin_HEXAGON_S2_lsr_i_vw, {{ 1, false, 5, 0 }} }, |
2849 | { Hexagon::BI__builtin_HEXAGON_S2_setbit_i, {{ 1, false, 5, 0 }} }, |
2850 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxb_goodsyntax, |
2851 | {{ 2, false, 4, 0 }, |
2852 | { 3, false, 5, 0 }} }, |
2853 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxd_goodsyntax, |
2854 | {{ 2, false, 4, 0 }, |
2855 | { 3, false, 5, 0 }} }, |
2856 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxh_goodsyntax, |
2857 | {{ 2, false, 4, 0 }, |
2858 | { 3, false, 5, 0 }} }, |
2859 | { Hexagon::BI__builtin_HEXAGON_S2_tableidxw_goodsyntax, |
2860 | {{ 2, false, 4, 0 }, |
2861 | { 3, false, 5, 0 }} }, |
2862 | { Hexagon::BI__builtin_HEXAGON_S2_togglebit_i, {{ 1, false, 5, 0 }} }, |
2863 | { Hexagon::BI__builtin_HEXAGON_S2_tstbit_i, {{ 1, false, 5, 0 }} }, |
2864 | { Hexagon::BI__builtin_HEXAGON_S2_valignib, {{ 2, false, 3, 0 }} }, |
2865 | { Hexagon::BI__builtin_HEXAGON_S2_vspliceib, {{ 2, false, 3, 0 }} }, |
2866 | { Hexagon::BI__builtin_HEXAGON_S4_addi_asl_ri, {{ 2, false, 5, 0 }} }, |
2867 | { Hexagon::BI__builtin_HEXAGON_S4_addi_lsr_ri, {{ 2, false, 5, 0 }} }, |
2868 | { Hexagon::BI__builtin_HEXAGON_S4_andi_asl_ri, {{ 2, false, 5, 0 }} }, |
2869 | { Hexagon::BI__builtin_HEXAGON_S4_andi_lsr_ri, {{ 2, false, 5, 0 }} }, |
2870 | { Hexagon::BI__builtin_HEXAGON_S4_clbaddi, {{ 1, true , 6, 0 }} }, |
2871 | { Hexagon::BI__builtin_HEXAGON_S4_clbpaddi, {{ 1, true, 6, 0 }} }, |
2872 | { Hexagon::BI__builtin_HEXAGON_S4_extract, {{ 1, false, 5, 0 }, |
2873 | { 2, false, 5, 0 }} }, |
2874 | { Hexagon::BI__builtin_HEXAGON_S4_extractp, {{ 1, false, 6, 0 }, |
2875 | { 2, false, 6, 0 }} }, |
2876 | { Hexagon::BI__builtin_HEXAGON_S4_lsli, {{ 0, true, 6, 0 }} }, |
2877 | { Hexagon::BI__builtin_HEXAGON_S4_ntstbit_i, {{ 1, false, 5, 0 }} }, |
2878 | { Hexagon::BI__builtin_HEXAGON_S4_ori_asl_ri, {{ 2, false, 5, 0 }} }, |
2879 | { Hexagon::BI__builtin_HEXAGON_S4_ori_lsr_ri, {{ 2, false, 5, 0 }} }, |
2880 | { Hexagon::BI__builtin_HEXAGON_S4_subi_asl_ri, {{ 2, false, 5, 0 }} }, |
2881 | { Hexagon::BI__builtin_HEXAGON_S4_subi_lsr_ri, {{ 2, false, 5, 0 }} }, |
2882 | { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate_acc, {{ 3, false, 2, 0 }} }, |
2883 | { Hexagon::BI__builtin_HEXAGON_S4_vrcrotate, {{ 2, false, 2, 0 }} }, |
2884 | { Hexagon::BI__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax, |
2885 | {{ 1, false, 4, 0 }} }, |
2886 | { Hexagon::BI__builtin_HEXAGON_S5_asrhub_sat, {{ 1, false, 4, 0 }} }, |
2887 | { Hexagon::BI__builtin_HEXAGON_S5_vasrhrnd_goodsyntax, |
2888 | {{ 1, false, 4, 0 }} }, |
2889 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p, {{ 1, false, 6, 0 }} }, |
2890 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_acc, {{ 2, false, 6, 0 }} }, |
2891 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_and, {{ 2, false, 6, 0 }} }, |
2892 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_nac, {{ 2, false, 6, 0 }} }, |
2893 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_or, {{ 2, false, 6, 0 }} }, |
2894 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_xacc, {{ 2, false, 6, 0 }} }, |
2895 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r, {{ 1, false, 5, 0 }} }, |
2896 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_acc, {{ 2, false, 5, 0 }} }, |
2897 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_and, {{ 2, false, 5, 0 }} }, |
2898 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_nac, {{ 2, false, 5, 0 }} }, |
2899 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_or, {{ 2, false, 5, 0 }} }, |
2900 | { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_xacc, {{ 2, false, 5, 0 }} }, |
2901 | { Hexagon::BI__builtin_HEXAGON_V6_valignbi, {{ 2, false, 3, 0 }} }, |
2902 | { Hexagon::BI__builtin_HEXAGON_V6_valignbi_128B, {{ 2, false, 3, 0 }} }, |
2903 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi, {{ 2, false, 3, 0 }} }, |
2904 | { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi_128B, {{ 2, false, 3, 0 }} }, |
2905 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi, {{ 2, false, 1, 0 }} }, |
2906 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_128B, {{ 2, false, 1, 0 }} }, |
2907 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc, {{ 3, false, 1, 0 }} }, |
2908 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc_128B, |
2909 | {{ 3, false, 1, 0 }} }, |
2910 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi, {{ 2, false, 1, 0 }} }, |
2911 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_128B, {{ 2, false, 1, 0 }} }, |
2912 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc, {{ 3, false, 1, 0 }} }, |
2913 | { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc_128B, |
2914 | {{ 3, false, 1, 0 }} }, |
2915 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi, {{ 2, false, 1, 0 }} }, |
2916 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_128B, {{ 2, false, 1, 0 }} }, |
2917 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc, {{ 3, false, 1, 0 }} }, |
2918 | { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc_128B, |
2919 | {{ 3, false, 1, 0 }} }, |
2920 | }; |
2921 | |
2922 | |
2923 | |
2924 | static const bool SortOnce = |
2925 | (llvm::sort(Infos, |
2926 | [](const BuiltinInfo &LHS, const BuiltinInfo &RHS) { |
2927 | return LHS.BuiltinID < RHS.BuiltinID; |
2928 | }), |
2929 | true); |
2930 | (void)SortOnce; |
2931 | |
2932 | const BuiltinInfo *F = |
2933 | std::lower_bound(std::begin(Infos), std::end(Infos), BuiltinID, |
2934 | [](const BuiltinInfo &BI, unsigned BuiltinID) { |
2935 | return BI.BuiltinID < BuiltinID; |
2936 | }); |
2937 | if (F == std::end(Infos) || F->BuiltinID != BuiltinID) |
2938 | return false; |
2939 | |
2940 | bool Error = false; |
2941 | |
2942 | for (const ArgInfo &A : F->Infos) { |
2943 | |
2944 | if (A.BitWidth == 0) |
2945 | continue; |
2946 | |
2947 | int32_t Min = A.IsSigned ? -(1 << (A.BitWidth - 1)) : 0; |
2948 | int32_t Max = (1 << (A.IsSigned ? A.BitWidth - 1 : A.BitWidth)) - 1; |
2949 | if (!A.Align) { |
2950 | Error |= SemaBuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); |
2951 | } else { |
2952 | unsigned M = 1 << A.Align; |
2953 | Min *= M; |
2954 | Max *= M; |
2955 | Error |= SemaBuiltinConstantArgRange(TheCall, A.OpNum, Min, Max) | |
2956 | SemaBuiltinConstantArgMultiple(TheCall, A.OpNum, M); |
2957 | } |
2958 | } |
2959 | return Error; |
2960 | } |
2961 | |
2962 | bool Sema::CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, |
2963 | CallExpr *TheCall) { |
2964 | return CheckHexagonBuiltinCpu(BuiltinID, TheCall) || |
2965 | CheckHexagonBuiltinArgument(BuiltinID, TheCall); |
2966 | } |
2967 | |
2968 | |
2969 | |
2970 | |
2971 | |
2972 | |
2973 | |
2974 | |
2975 | |
2976 | |
2977 | |
2978 | bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { |
2979 | unsigned i = 0, l = 0, u = 0, m = 0; |
2980 | switch (BuiltinID) { |
2981 | default: return false; |
2982 | case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; |
2983 | case Mips::BI__builtin_mips_rddsp: i = 0; l = 0; u = 63; break; |
2984 | case Mips::BI__builtin_mips_append: i = 2; l = 0; u = 31; break; |
2985 | case Mips::BI__builtin_mips_balign: i = 2; l = 0; u = 3; break; |
2986 | case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break; |
2987 | case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break; |
2988 | case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; |
2989 | |
2990 | |
2991 | |
2992 | case Mips::BI__builtin_msa_bclri_b: |
2993 | case Mips::BI__builtin_msa_bnegi_b: |
2994 | case Mips::BI__builtin_msa_bseti_b: |
2995 | case Mips::BI__builtin_msa_sat_s_b: |
2996 | case Mips::BI__builtin_msa_sat_u_b: |
2997 | case Mips::BI__builtin_msa_slli_b: |
2998 | case Mips::BI__builtin_msa_srai_b: |
2999 | case Mips::BI__builtin_msa_srari_b: |
3000 | case Mips::BI__builtin_msa_srli_b: |
3001 | case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break; |
3002 | case Mips::BI__builtin_msa_binsli_b: |
3003 | case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break; |
3004 | |
3005 | case Mips::BI__builtin_msa_bclri_h: |
3006 | case Mips::BI__builtin_msa_bnegi_h: |
3007 | case Mips::BI__builtin_msa_bseti_h: |
3008 | case Mips::BI__builtin_msa_sat_s_h: |
3009 | case Mips::BI__builtin_msa_sat_u_h: |
3010 | case Mips::BI__builtin_msa_slli_h: |
3011 | case Mips::BI__builtin_msa_srai_h: |
3012 | case Mips::BI__builtin_msa_srari_h: |
3013 | case Mips::BI__builtin_msa_srli_h: |
3014 | case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break; |
3015 | case Mips::BI__builtin_msa_binsli_h: |
3016 | case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break; |
3017 | |
3018 | |
3019 | |
3020 | case Mips::BI__builtin_msa_clei_u_b: |
3021 | case Mips::BI__builtin_msa_clei_u_h: |
3022 | case Mips::BI__builtin_msa_clei_u_w: |
3023 | case Mips::BI__builtin_msa_clei_u_d: |
3024 | case Mips::BI__builtin_msa_clti_u_b: |
3025 | case Mips::BI__builtin_msa_clti_u_h: |
3026 | case Mips::BI__builtin_msa_clti_u_w: |
3027 | case Mips::BI__builtin_msa_clti_u_d: |
3028 | case Mips::BI__builtin_msa_maxi_u_b: |
3029 | case Mips::BI__builtin_msa_maxi_u_h: |
3030 | case Mips::BI__builtin_msa_maxi_u_w: |
3031 | case Mips::BI__builtin_msa_maxi_u_d: |
3032 | case Mips::BI__builtin_msa_mini_u_b: |
3033 | case Mips::BI__builtin_msa_mini_u_h: |
3034 | case Mips::BI__builtin_msa_mini_u_w: |
3035 | case Mips::BI__builtin_msa_mini_u_d: |
3036 | case Mips::BI__builtin_msa_addvi_b: |
3037 | case Mips::BI__builtin_msa_addvi_h: |
3038 | case Mips::BI__builtin_msa_addvi_w: |
3039 | case Mips::BI__builtin_msa_addvi_d: |
3040 | case Mips::BI__builtin_msa_bclri_w: |
3041 | case Mips::BI__builtin_msa_bnegi_w: |
3042 | case Mips::BI__builtin_msa_bseti_w: |
3043 | case Mips::BI__builtin_msa_sat_s_w: |
3044 | case Mips::BI__builtin_msa_sat_u_w: |
3045 | case Mips::BI__builtin_msa_slli_w: |
3046 | case Mips::BI__builtin_msa_srai_w: |
3047 | case Mips::BI__builtin_msa_srari_w: |
3048 | case Mips::BI__builtin_msa_srli_w: |
3049 | case Mips::BI__builtin_msa_srlri_w: |
3050 | case Mips::BI__builtin_msa_subvi_b: |
3051 | case Mips::BI__builtin_msa_subvi_h: |
3052 | case Mips::BI__builtin_msa_subvi_w: |
3053 | case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break; |
3054 | case Mips::BI__builtin_msa_binsli_w: |
3055 | case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break; |
3056 | |
3057 | case Mips::BI__builtin_msa_bclri_d: |
3058 | case Mips::BI__builtin_msa_bnegi_d: |
3059 | case Mips::BI__builtin_msa_bseti_d: |
3060 | case Mips::BI__builtin_msa_sat_s_d: |
3061 | case Mips::BI__builtin_msa_sat_u_d: |
3062 | case Mips::BI__builtin_msa_slli_d: |
3063 | case Mips::BI__builtin_msa_srai_d: |
3064 | case Mips::BI__builtin_msa_srari_d: |
3065 | case Mips::BI__builtin_msa_srli_d: |
3066 | case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break; |
3067 | case Mips::BI__builtin_msa_binsli_d: |
3068 | case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break; |
3069 | |
3070 | case Mips::BI__builtin_msa_ceqi_b: |
3071 | case Mips::BI__builtin_msa_ceqi_h: |
3072 | case Mips::BI__builtin_msa_ceqi_w: |
3073 | case Mips::BI__builtin_msa_ceqi_d: |
3074 | case Mips::BI__builtin_msa_clti_s_b: |
3075 | case Mips::BI__builtin_msa_clti_s_h: |
3076 | case Mips::BI__builtin_msa_clti_s_w: |
3077 | case Mips::BI__builtin_msa_clti_s_d: |
3078 | case Mips::BI__builtin_msa_clei_s_b: |
3079 | case Mips::BI__builtin_msa_clei_s_h: |
3080 | case Mips::BI__builtin_msa_clei_s_w: |
3081 | case Mips::BI__builtin_msa_clei_s_d: |
3082 | case Mips::BI__builtin_msa_maxi_s_b: |
3083 | case Mips::BI__builtin_msa_maxi_s_h: |
3084 | case Mips::BI__builtin_msa_maxi_s_w: |
3085 | case Mips::BI__builtin_msa_maxi_s_d: |
3086 | case Mips::BI__builtin_msa_mini_s_b: |
3087 | case Mips::BI__builtin_msa_mini_s_h: |
3088 | case Mips::BI__builtin_msa_mini_s_w: |
3089 | case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break; |
3090 | |
3091 | case Mips::BI__builtin_msa_andi_b: |
3092 | case Mips::BI__builtin_msa_nori_b: |
3093 | case Mips::BI__builtin_msa_ori_b: |
3094 | case Mips::BI__builtin_msa_shf_b: |
3095 | case Mips::BI__builtin_msa_shf_h: |
3096 | case Mips::BI__builtin_msa_shf_w: |
3097 | case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break; |
3098 | case Mips::BI__builtin_msa_bseli_b: |
3099 | case Mips::BI__builtin_msa_bmnzi_b: |
3100 | case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break; |
3101 | |
3102 | |
3103 | case Mips::BI__builtin_msa_copy_s_b: |
3104 | case Mips::BI__builtin_msa_copy_u_b: |
3105 | case Mips::BI__builtin_msa_insve_b: |
3106 | case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; |
3107 | case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; |
3108 | |
3109 | case Mips::BI__builtin_msa_copy_s_h: |
3110 | case Mips::BI__builtin_msa_copy_u_h: |
3111 | case Mips::BI__builtin_msa_insve_h: |
3112 | case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; |
3113 | case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; |
3114 | |
3115 | case Mips::BI__builtin_msa_copy_s_w: |
3116 | case Mips::BI__builtin_msa_copy_u_w: |
3117 | case Mips::BI__builtin_msa_insve_w: |
3118 | case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; |
3119 | case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; |
3120 | |
3121 | case Mips::BI__builtin_msa_copy_s_d: |
3122 | case Mips::BI__builtin_msa_copy_u_d: |
3123 | case Mips::BI__builtin_msa_insve_d: |
3124 | case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; |
3125 | case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; |
3126 | |
3127 | |
3128 | case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break; |
3129 | case Mips::BI__builtin_msa_ldi_h: |
3130 | case Mips::BI__builtin_msa_ldi_w: |
3131 | case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; |
3132 | case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 1; break; |
3133 | case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 2; break; |
3134 | case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 4; break; |
3135 | case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 8; break; |
3136 | case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 1; break; |
3137 | case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 2; break; |
3138 | case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 4; break; |
3139 | case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 8; break; |
3140 | } |
3141 | |
3142 | if (!m) |
3143 | return SemaBuiltinConstantArgRange(TheCall, i, l, u); |
3144 | |
3145 | return SemaBuiltinConstantArgRange(TheCall, i, l, u) || |
3146 | SemaBuiltinConstantArgMultiple(TheCall, i, m); |
3147 | } |
3148 | |
3149 | bool Sema::CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { |
3150 | unsigned i = 0, l = 0, u = 0; |
3151 | bool Is64BitBltin = BuiltinID == PPC::BI__builtin_divde || |
3152 | BuiltinID == PPC::BI__builtin_divdeu || |
3153 | BuiltinID == PPC::BI__builtin_bpermd; |
3154 | bool IsTarget64Bit = Context.getTargetInfo() |
3155 | .getTypeWidth(Context |
3156 | .getTargetInfo() |
3157 | .getIntPtrType()) == 64; |
3158 | bool IsBltinExtDiv = BuiltinID == PPC::BI__builtin_divwe || |
3159 | BuiltinID == PPC::BI__builtin_divweu || |
3160 | BuiltinID == PPC::BI__builtin_divde || |
3161 | BuiltinID == PPC::BI__builtin_divdeu; |
3162 | |
3163 | if (Is64BitBltin && !IsTarget64Bit) |
3164 | return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt) |
3165 | << TheCall->getSourceRange(); |
3166 | |
3167 | if ((IsBltinExtDiv && !Context.getTargetInfo().hasFeature("extdiv")) || |
3168 | (BuiltinID == PPC::BI__builtin_bpermd && |
3169 | !Context.getTargetInfo().hasFeature("bpermd"))) |
3170 | return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_only_on_pwr7) |
3171 | << TheCall->getSourceRange(); |
3172 | |
3173 | auto SemaVSXCheck = [&](CallExpr *TheCall) -> bool { |
3174 | if (!Context.getTargetInfo().hasFeature("vsx")) |
3175 | return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_only_on_pwr7) |
3176 | << TheCall->getSourceRange(); |
3177 | return false; |
3178 | }; |
3179 | |
3180 | switch (BuiltinID) { |
3181 | default: return false; |
3182 | case PPC::BI__builtin_altivec_crypto_vshasigmaw: |
3183 | case PPC::BI__builtin_altivec_crypto_vshasigmad: |
3184 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) || |
3185 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 15); |
3186 | case PPC::BI__builtin_tbegin: |
3187 | case PPC::BI__builtin_tend: i = 0; l = 0; u = 1; break; |
3188 | case PPC::BI__builtin_tsr: i = 0; l = 0; u = 7; break; |
3189 | case PPC::BI__builtin_tabortwc: |
3190 | case PPC::BI__builtin_tabortdc: i = 0; l = 0; u = 31; break; |
3191 | case PPC::BI__builtin_tabortwci: |
3192 | case PPC::BI__builtin_tabortdci: |
3193 | return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31) || |
3194 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 31); |
3195 | case PPC::BI__builtin_vsx_xxpermdi: |
3196 | case PPC::BI__builtin_vsx_xxsldwi: |
3197 | return SemaBuiltinVSX(TheCall); |
3198 | case PPC::BI__builtin_unpack_vector_int128: |
3199 | return SemaVSXCheck(TheCall) || |
3200 | SemaBuiltinConstantArgRange(TheCall, 1, 0, 1); |
3201 | case PPC::BI__builtin_pack_vector_int128: |
3202 | return SemaVSXCheck(TheCall); |
3203 | } |
3204 | return SemaBuiltinConstantArgRange(TheCall, i, l, u); |
3205 | } |
3206 | |
3207 | bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, |
3208 | CallExpr *TheCall) { |
3209 | if (BuiltinID == SystemZ::BI__builtin_tabort) { |
3210 | Expr *Arg = TheCall->getArg(0); |
3211 | llvm::APSInt AbortCode(32); |
3212 | if (Arg->isIntegerConstantExpr(AbortCode, Context) && |
3213 | AbortCode.getSExtValue() >= 0 && AbortCode.getSExtValue() < 256) |
3214 | return Diag(Arg->getBeginLoc(), diag::err_systemz_invalid_tabort_code) |
3215 | << Arg->getSourceRange(); |
3216 | } |
3217 | |
3218 | |
3219 | |
3220 | unsigned i = 0, l = 0, u = 0; |
3221 | switch (BuiltinID) { |
3222 | default: return false; |
3223 | case SystemZ::BI__builtin_s390_lcbb: i = 1; l = 0; u = 15; break; |
3224 | case SystemZ::BI__builtin_s390_verimb: |
3225 | case SystemZ::BI__builtin_s390_verimh: |
3226 | case SystemZ::BI__builtin_s390_verimf: |
3227 | case SystemZ::BI__builtin_s390_verimg: i = 3; l = 0; u = 255; break; |
3228 | case SystemZ::BI__builtin_s390_vfaeb: |
3229 | case SystemZ::BI__builtin_s390_vfaeh: |
3230 | case SystemZ::BI__builtin_s390_vfaef: |
3231 | case SystemZ::BI__builtin_s390_vfaebs: |
3232 | case SystemZ::BI__builtin_s390_vfaehs: |
3233 | case SystemZ::BI__builtin_s390_vfaefs: |
3234 | case SystemZ::BI__builtin_s390_vfaezb: |
3235 | case SystemZ::BI__builtin_s390_vfaezh: |
3236 | case SystemZ::BI__builtin_s390_vfaezf: |
3237 | case SystemZ::BI__builtin_s390_vfaezbs: |
3238 | case SystemZ::BI__builtin_s390_vfaezhs: |
3239 | case SystemZ::BI__builtin_s390_vfaezfs: i = 2; l = 0; u = 15; break; |
3240 | case SystemZ::BI__builtin_s390_vfisb: |
3241 | case SystemZ::BI__builtin_s390_vfidb: |
3242 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15) || |
3243 | SemaBuiltinConstantArgRange(TheCall, 2, 0, 15); |
3244 | case SystemZ::BI__builtin_s390_vftcisb: |
3245 | case SystemZ::BI__builtin_s390_vftcidb: i = 1; l = 0; u = 4095; break; |
3246 | case SystemZ::BI__builtin_s390_vlbb: i = 1; l = 0; u = 15; break; |
3247 | case SystemZ::BI__builtin_s390_vpdi: i = 2; l = 0; u = 15; break; |
3248 | case SystemZ::BI__builtin_s390_vsldb: i = 2; l = 0; u = 15; break; |
3249 | case SystemZ::BI__builtin_s390_vstrcb: |
3250 | case SystemZ::BI__builtin_s390_vstrch: |
3251 | case SystemZ::BI__builtin_s390_vstrcf: |
3252 | case SystemZ::BI__builtin_s390_vstrczb: |
3253 | case SystemZ::BI__builtin_s390_vstrczh: |
3254 | case SystemZ::BI__builtin_s390_vstrczf: |
3255 | case SystemZ::BI__builtin_s390_vstrcbs: |
3256 | case SystemZ::BI__builtin_s390_vstrchs: |
3257 | case SystemZ::BI__builtin_s390_vstrcfs: |
3258 | case SystemZ::BI__builtin_s390_vstrczbs: |
3259 | case SystemZ::BI__builtin_s390_vstrczhs: |
3260 | case SystemZ::BI__builtin_s390_vstrczfs: i = 3; l = 0; u = 15; break; |
3261 | case SystemZ::BI__builtin_s390_vmslg: i = 3; l = 0; u = 15; break; |
3262 | case SystemZ::BI__builtin_s390_vfminsb: |
3263 | case SystemZ::BI__builtin_s390_vfmaxsb: |
3264 | case SystemZ::BI__builtin_s390_vfmindb: |
3265 | case SystemZ::BI__builtin_s390_vfmaxdb: i = 2; l = 0; u = 15; break; |
3266 | } |
3267 | return SemaBuiltinConstantArgRange(TheCall, i, l, u); |
3268 | } |
3269 | |
3270 | |
3271 | |
3272 | |
3273 | static bool SemaBuiltinCpuSupports(Sema &S, CallExpr *TheCall) { |
3274 | Expr *Arg = TheCall->getArg(0); |
3275 | |
3276 | |
3277 | if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts())) |
3278 | return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal) |
3279 | << Arg->getSourceRange(); |
3280 | |
3281 | |
3282 | StringRef Feature = |
3283 | cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString(); |
3284 | if (!S.Context.getTargetInfo().validateCpuSupports(Feature)) |
3285 | return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_supports) |
3286 | << Arg->getSourceRange(); |
3287 | return false; |
3288 | } |
3289 | |
3290 | |
3291 | |
3292 | |
3293 | static bool SemaBuiltinCpuIs(Sema &S, CallExpr *TheCall) { |
3294 | Expr *Arg = TheCall->getArg(0); |
3295 | |
3296 | |
3297 | if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts())) |
3298 | return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal) |
3299 | << Arg->getSourceRange(); |
3300 | |
3301 | |
3302 | StringRef Feature = |
3303 | cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString(); |
3304 | if (!S.Context.getTargetInfo().validateCpuIs(Feature)) |
3305 | return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_is) |
3306 | << Arg->getSourceRange(); |
3307 | return false; |
3308 | } |
3309 | |
3310 | |
3311 | bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { |
3312 | |
3313 | bool HasRC = false; |
3314 | |
3315 | unsigned ArgNum = 0; |
3316 | switch (BuiltinID) { |
3317 | default: |
3318 | return false; |
3319 | case X86::BI__builtin_ia32_vcvttsd2si32: |
3320 | case X86::BI__builtin_ia32_vcvttsd2si64: |
3321 | case X86::BI__builtin_ia32_vcvttsd2usi32: |
3322 | case X86::BI__builtin_ia32_vcvttsd2usi64: |
3323 | case X86::BI__builtin_ia32_vcvttss2si32: |
3324 | case X86::BI__builtin_ia32_vcvttss2si64: |
3325 | case X86::BI__builtin_ia32_vcvttss2usi32: |
3326 | case X86::BI__builtin_ia32_vcvttss2usi64: |
3327 | ArgNum = 1; |
3328 | break; |
3329 | case X86::BI__builtin_ia32_maxpd512: |
3330 | case X86::BI__builtin_ia32_maxps512: |
3331 | case X86::BI__builtin_ia32_minpd512: |
3332 | case X86::BI__builtin_ia32_minps512: |
3333 | ArgNum = 2; |
3334 | break; |
3335 | case X86::BI__builtin_ia32_cvtps2pd512_mask: |
3336 | case X86::BI__builtin_ia32_cvttpd2dq512_mask: |
3337 | case X86::BI__builtin_ia32_cvttpd2qq512_mask: |
3338 | case X86::BI__builtin_ia32_cvttpd2udq512_mask: |
3339 | case X86::BI__builtin_ia32_cvttpd2uqq512_mask: |
3340 | case X86::BI__builtin_ia32_cvttps2dq512_mask: |
3341 | case X86::BI__builtin_ia32_cvttps2qq512_mask: |
3342 | case X86::BI__builtin_ia32_cvttps2udq512_mask: |
3343 | case X86::BI__builtin_ia32_cvttps2uqq512_mask: |
3344 | case X86::BI__builtin_ia32_exp2pd_mask: |
3345 | case X86::BI__builtin_ia32_exp2ps_mask: |
3346 | case X86::BI__builtin_ia32_getexppd512_mask: |
3347 | case X86::BI__builtin_ia32_getexpps512_mask: |
3348 | case X86::BI__builtin_ia32_rcp28pd_mask: |
3349 | case X86::BI__builtin_ia32_rcp28ps_mask: |
3350 | case X86::BI__builtin_ia32_rsqrt28pd_mask: |
3351 | case X86::BI__builtin_ia32_rsqrt28ps_mask: |
3352 | case X86::BI__builtin_ia32_vcomisd: |
3353 | case X86::BI__builtin_ia32_vcomiss: |
3354 | case X86::BI__builtin_ia32_vcvtph2ps512_mask: |
3355 | ArgNum = 3; |
3356 | break; |
3357 | case X86::BI__builtin_ia32_cmppd512_mask: |
3358 | case X86::BI__builtin_ia32_cmpps512_mask: |
3359 | case X86::BI__builtin_ia32_cmpsd_mask: |
3360 | case X86::BI__builtin_ia32_cmpss_mask: |
3361 | case X86::BI__builtin_ia32_cvtss2sd_round_mask: |
3362 | case X86::BI__builtin_ia32_getexpsd128_round_mask: |
3363 | case X86::BI__builtin_ia32_getexpss128_round_mask: |
3364 | case X86::BI__builtin_ia32_maxsd_round_mask: |
3365 | case X86::BI__builtin_ia32_maxss_round_mask: |
3366 | case X86::BI__builtin_ia32_minsd_round_mask: |
3367 | case X86::BI__builtin_ia32_minss_round_mask: |
3368 | case X86::BI__builtin_ia32_rcp28sd_round_mask: |
3369 | case X86::BI__builtin_ia32_rcp28ss_round_mask: |
3370 | case X86::BI__builtin_ia32_reducepd512_mask: |
3371 | case X86::BI__builtin_ia32_reduceps512_mask: |
3372 | case X86::BI__builtin_ia32_rndscalepd_mask: |
3373 | case X86::BI__builtin_ia32_rndscaleps_mask: |
3374 | case X86::BI__builtin_ia32_rsqrt28sd_round_mask: |
3375 | case X86::BI__builtin_ia32_rsqrt28ss_round_mask: |
3376 | ArgNum = 4; |
3377 | break; |
3378 | case X86::BI__builtin_ia32_fixupimmpd512_mask: |
3379 | case X86::BI__builtin_ia32_fixupimmpd512_maskz: |
3380 | case X86::BI__builtin_ia32_fixupimmps512_mask: |
3381 | case X86::BI__builtin_ia32_fixupimmps512_maskz: |
3382 | case X86::BI__builtin_ia32_fixupimmsd_mask: |
3383 | case X86::BI__builtin_ia32_fixupimmsd_maskz: |
3384 | case X86::BI__builtin_ia32_fixupimmss_mask: |
3385 | case X86::BI__builtin_ia32_fixupimmss_maskz: |
3386 | case X86::BI__builtin_ia32_rangepd512_mask: |
3387 | case X86::BI__builtin_ia32_rangeps512_mask: |
3388 | case X86::BI__builtin_ia32_rangesd128_round_mask: |
3389 | case X86::BI__builtin_ia32_rangess128_round_mask: |
3390 | case X86::BI__builtin_ia32_reducesd_mask: |
3391 | case X86::BI__builtin_ia32_reducess_mask: |
3392 | case X86::BI__builtin_ia32_rndscalesd_round_mask: |
3393 | case X86::BI__builtin_ia32_rndscaless_round_mask: |
3394 | ArgNum = 5; |
3395 | break; |
3396 | case X86::BI__builtin_ia32_vcvtsd2si64: |
3397 | case X86::BI__builtin_ia32_vcvtsd2si32: |
3398 | case X86::BI__builtin_ia32_vcvtsd2usi32: |
3399 | case X86::BI__builtin_ia32_vcvtsd2usi64: |
3400 | case X86::BI__builtin_ia32_vcvtss2si32: |
3401 | case X86::BI__builtin_ia32_vcvtss2si64: |
3402 | case X86::BI__builtin_ia32_vcvtss2usi32: |
3403 | case X86::BI__builtin_ia32_vcvtss2usi64: |
3404 | case X86::BI__builtin_ia32_sqrtpd512: |
3405 | case X86::BI__builtin_ia32_sqrtps512: |
3406 | ArgNum = 1; |
3407 | HasRC = true; |
3408 | break; |
3409 | case X86::BI__builtin_ia32_addpd512: |
3410 | case X86::BI__builtin_ia32_addps512: |
3411 | case X86::BI__builtin_ia32_divpd512: |
3412 | case X86::BI__builtin_ia32_divps512: |
3413 | case X86::BI__builtin_ia32_mulpd512: |
3414 | case X86::BI__builtin_ia32_mulps512: |
3415 | case X86::BI__builtin_ia32_subpd512: |
3416 | case X86::BI__builtin_ia32_subps512: |
3417 | case X86::BI__builtin_ia32_cvtsi2sd64: |
3418 | case X86::BI__builtin_ia32_cvtsi2ss32: |
3419 | case X86::BI__builtin_ia32_cvtsi2ss64: |
3420 | case X86::BI__builtin_ia32_cvtusi2sd64: |
3421 | case X86::BI__builtin_ia32_cvtusi2ss32: |
3422 | case X86::BI__builtin_ia32_cvtusi2ss64: |
3423 | ArgNum = 2; |
3424 | HasRC = true; |
3425 | break; |
3426 | case X86::BI__builtin_ia32_cvtdq2ps512_mask: |
3427 | case X86::BI__builtin_ia32_cvtudq2ps512_mask: |
3428 | case X86::BI__builtin_ia32_cvtpd2ps512_mask: |
3429 | case X86::BI__builtin_ia32_cvtpd2qq512_mask: |
3430 | case X86::BI__builtin_ia32_cvtpd2uqq512_mask: |
3431 | case X86::BI__builtin_ia32_cvtps2qq512_mask: |
3432 | case X86::BI__builtin_ia32_cvtps2uqq512_mask: |
3433 | case X86::BI__builtin_ia32_cvtqq2pd512_mask: |
3434 | case X86::BI__builtin_ia32_cvtqq2ps512_mask: |
3435 | case X86::BI__builtin_ia32_cvtuqq2pd512_mask: |
3436 | case X86::BI__builtin_ia32_cvtuqq2ps512_mask: |
3437 | ArgNum = 3; |
3438 | HasRC = true; |
3439 | break; |
3440 | case X86::BI__builtin_ia32_addss_round_mask: |
3441 | case X86::BI__builtin_ia32_addsd_round_mask: |
3442 | case X86::BI__builtin_ia32_divss_round_mask: |
3443 | case X86::BI__builtin_ia32_divsd_round_mask: |
3444 | case X86::BI__builtin_ia32_mulss_round_mask: |
3445 | case X86::BI__builtin_ia32_mulsd_round_mask: |
3446 | case X86::BI__builtin_ia32_subss_round_mask: |
3447 | case X86::BI__builtin_ia32_subsd_round_mask: |
3448 | case X86::BI__builtin_ia32_scalefpd512_mask: |
3449 | case X86::BI__builtin_ia32_scalefps512_mask: |
3450 | case X86::BI__builtin_ia32_scalefsd_round_mask: |
3451 | case X86::BI__builtin_ia32_scalefss_round_mask: |
3452 | case X86::BI__builtin_ia32_getmantpd512_mask: |
3453 | case X86::BI__builtin_ia32_getmantps512_mask: |
3454 | case X86::BI__builtin_ia32_cvtsd2ss_round_mask: |
3455 | case X86::BI__builtin_ia32_sqrtsd_round_mask: |
3456 | case X86::BI__builtin_ia32_sqrtss_round_mask: |
3457 | case X86::BI__builtin_ia32_vfmaddsd3_mask: |
3458 | case X86::BI__builtin_ia32_vfmaddsd3_maskz: |
3459 | case X86::BI__builtin_ia32_vfmaddsd3_mask3: |
3460 | case X86::BI__builtin_ia32_vfmaddss3_mask: |
3461 | case X86::BI__builtin_ia32_vfmaddss3_maskz: |
3462 | case X86::BI__builtin_ia32_vfmaddss3_mask3: |
3463 | case X86::BI__builtin_ia32_vfmaddpd512_mask: |
3464 | case X86::BI__builtin_ia32_vfmaddpd512_maskz: |
3465 | case X86::BI__builtin_ia32_vfmaddpd512_mask3: |
3466 | case X86::BI__builtin_ia32_vfmsubpd512_mask3: |
3467 | case X86::BI__builtin_ia32_vfmaddps512_mask: |
3468 | case X86::BI__builtin_ia32_vfmaddps512_maskz: |
3469 | case X86::BI__builtin_ia32_vfmaddps512_mask3: |
3470 | case X86::BI__builtin_ia32_vfmsubps512_mask3: |
3471 | case X86::BI__builtin_ia32_vfmaddsubpd512_mask: |
3472 | case X86::BI__builtin_ia32_vfmaddsubpd512_maskz: |
3473 | case X86::BI__builtin_ia32_vfmaddsubpd512_mask3: |
3474 | case X86::BI__builtin_ia32_vfmsubaddpd512_mask3: |
3475 | case X86::BI__builtin_ia32_vfmaddsubps512_mask: |
3476 | case X86::BI__builtin_ia32_vfmaddsubps512_maskz: |
3477 | case X86::BI__builtin_ia32_vfmaddsubps512_mask3: |
3478 | case X86::BI__builtin_ia32_vfmsubaddps512_mask3: |
3479 | ArgNum = 4; |
3480 | HasRC = true; |
3481 | break; |
3482 | case X86::BI__builtin_ia32_getmantsd_round_mask: |
3483 | case X86::BI__builtin_ia32_getmantss_round_mask: |
3484 | ArgNum = 5; |
3485 | HasRC = true; |
3486 | break; |
3487 | } |
3488 | |
3489 | llvm::APSInt Result; |
3490 | |
3491 | |
3492 | Expr *Arg = TheCall->getArg(ArgNum); |
3493 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
3494 | return false; |
3495 | |
3496 | |
3497 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
3498 | return true; |
3499 | |
3500 | |
3501 | |
3502 | |
3503 | if (Result == 4 || |
3504 | Result == 8 || |
3505 | (HasRC && Result.getZExtValue() >= 8 && Result.getZExtValue() <= 11)) |
3506 | return false; |
3507 | |
3508 | return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_rounding) |
3509 | << Arg->getSourceRange(); |
3510 | } |
3511 | |
3512 | |
3513 | bool Sema::CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, |
3514 | CallExpr *TheCall) { |
3515 | unsigned ArgNum = 0; |
3516 | switch (BuiltinID) { |
3517 | default: |
3518 | return false; |
3519 | case X86::BI__builtin_ia32_gatherpfdpd: |
3520 | case X86::BI__builtin_ia32_gatherpfdps: |
3521 | case X86::BI__builtin_ia32_gatherpfqpd: |
3522 | case X86::BI__builtin_ia32_gatherpfqps: |
3523 | case X86::BI__builtin_ia32_scatterpfdpd: |
3524 | case X86::BI__builtin_ia32_scatterpfdps: |
3525 | case X86::BI__builtin_ia32_scatterpfqpd: |
3526 | case X86::BI__builtin_ia32_scatterpfqps: |
3527 | ArgNum = 3; |
3528 | break; |
3529 | case X86::BI__builtin_ia32_gatherd_pd: |
3530 | case X86::BI__builtin_ia32_gatherd_pd256: |
3531 | case X86::BI__builtin_ia32_gatherq_pd: |
3532 | case X86::BI__builtin_ia32_gatherq_pd256: |
3533 | case X86::BI__builtin_ia32_gatherd_ps: |
3534 | case X86::BI__builtin_ia32_gatherd_ps256: |
3535 | case X86::BI__builtin_ia32_gatherq_ps: |
3536 | case X86::BI__builtin_ia32_gatherq_ps256: |
3537 | case X86::BI__builtin_ia32_gatherd_q: |
3538 | case X86::BI__builtin_ia32_gatherd_q256: |
3539 | case X86::BI__builtin_ia32_gatherq_q: |
3540 | case X86::BI__builtin_ia32_gatherq_q256: |
3541 | case X86::BI__builtin_ia32_gatherd_d: |
3542 | case X86::BI__builtin_ia32_gatherd_d256: |
3543 | case X86::BI__builtin_ia32_gatherq_d: |
3544 | case X86::BI__builtin_ia32_gatherq_d256: |
3545 | case X86::BI__builtin_ia32_gather3div2df: |
3546 | case X86::BI__builtin_ia32_gather3div2di: |
3547 | case X86::BI__builtin_ia32_gather3div4df: |
3548 | case X86::BI__builtin_ia32_gather3div4di: |
3549 | case X86::BI__builtin_ia32_gather3div4sf: |
3550 | case X86::BI__builtin_ia32_gather3div4si: |
3551 | case X86::BI__builtin_ia32_gather3div8sf: |
3552 | case X86::BI__builtin_ia32_gather3div8si: |
3553 | case X86::BI__builtin_ia32_gather3siv2df: |
3554 | case X86::BI__builtin_ia32_gather3siv2di: |
3555 | case X86::BI__builtin_ia32_gather3siv4df: |
3556 | case X86::BI__builtin_ia32_gather3siv4di: |
3557 | case X86::BI__builtin_ia32_gather3siv4sf: |
3558 | case X86::BI__builtin_ia32_gather3siv4si: |
3559 | case X86::BI__builtin_ia32_gather3siv8sf: |
3560 | case X86::BI__builtin_ia32_gather3siv8si: |
3561 | case X86::BI__builtin_ia32_gathersiv8df: |
3562 | case X86::BI__builtin_ia32_gathersiv16sf: |
3563 | case X86::BI__builtin_ia32_gatherdiv8df: |
3564 | case X86::BI__builtin_ia32_gatherdiv16sf: |
3565 | case X86::BI__builtin_ia32_gathersiv8di: |
3566 | case X86::BI__builtin_ia32_gathersiv16si: |
3567 | case X86::BI__builtin_ia32_gatherdiv8di: |
3568 | case X86::BI__builtin_ia32_gatherdiv16si: |
3569 | case X86::BI__builtin_ia32_scatterdiv2df: |
3570 | case X86::BI__builtin_ia32_scatterdiv2di: |
3571 | case X86::BI__builtin_ia32_scatterdiv4df: |
3572 | case X86::BI__builtin_ia32_scatterdiv4di: |
3573 | case X86::BI__builtin_ia32_scatterdiv4sf: |
3574 | case X86::BI__builtin_ia32_scatterdiv4si: |
3575 | case X86::BI__builtin_ia32_scatterdiv8sf: |
3576 | case X86::BI__builtin_ia32_scatterdiv8si: |
3577 | case X86::BI__builtin_ia32_scattersiv2df: |
3578 | case X86::BI__builtin_ia32_scattersiv2di: |
3579 | case X86::BI__builtin_ia32_scattersiv4df: |
3580 | case X86::BI__builtin_ia32_scattersiv4di: |
3581 | case X86::BI__builtin_ia32_scattersiv4sf: |
3582 | case X86::BI__builtin_ia32_scattersiv4si: |
3583 | case X86::BI__builtin_ia32_scattersiv8sf: |
3584 | case X86::BI__builtin_ia32_scattersiv8si: |
3585 | case X86::BI__builtin_ia32_scattersiv8df: |
3586 | case X86::BI__builtin_ia32_scattersiv16sf: |
3587 | case X86::BI__builtin_ia32_scatterdiv8df: |
3588 | case X86::BI__builtin_ia32_scatterdiv16sf: |
3589 | case X86::BI__builtin_ia32_scattersiv8di: |
3590 | case X86::BI__builtin_ia32_scattersiv16si: |
3591 | case X86::BI__builtin_ia32_scatterdiv8di: |
3592 | case X86::BI__builtin_ia32_scatterdiv16si: |
3593 | ArgNum = 4; |
3594 | break; |
3595 | } |
3596 | |
3597 | llvm::APSInt Result; |
3598 | |
3599 | |
3600 | Expr *Arg = TheCall->getArg(ArgNum); |
3601 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
3602 | return false; |
3603 | |
3604 | |
3605 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
3606 | return true; |
3607 | |
3608 | if (Result == 1 || Result == 2 || Result == 4 || Result == 8) |
3609 | return false; |
3610 | |
3611 | return Diag(TheCall->getBeginLoc(), diag::err_x86_builtin_invalid_scale) |
3612 | << Arg->getSourceRange(); |
3613 | } |
3614 | |
3615 | static bool isX86_32Builtin(unsigned BuiltinID) { |
3616 | |
3617 | switch (BuiltinID) { |
3618 | case X86::BI__builtin_ia32_readeflags_u32: |
3619 | case X86::BI__builtin_ia32_writeeflags_u32: |
3620 | return true; |
3621 | } |
3622 | |
3623 | return false; |
3624 | } |
3625 | |
3626 | bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { |
3627 | if (BuiltinID == X86::BI__builtin_cpu_supports) |
3628 | return SemaBuiltinCpuSupports(*this, TheCall); |
3629 | |
3630 | if (BuiltinID == X86::BI__builtin_cpu_is) |
3631 | return SemaBuiltinCpuIs(*this, TheCall); |
3632 | |
3633 | |
3634 | const llvm::Triple &TT = Context.getTargetInfo().getTriple(); |
3635 | if (TT.getArch() != llvm::Triple::x86 && isX86_32Builtin(BuiltinID)) |
3636 | return Diag(TheCall->getCallee()->getBeginLoc(), |
3637 | diag::err_32_bit_builtin_64_bit_tgt); |
3638 | |
3639 | |
3640 | if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall)) |
3641 | return true; |
3642 | |
3643 | |
3644 | if (CheckX86BuiltinGatherScatterScale(BuiltinID, TheCall)) |
3645 | return true; |
3646 | |
3647 | |
3648 | |
3649 | int i = 0, l = 0, u = 0; |
3650 | switch (BuiltinID) { |
3651 | default: |
3652 | return false; |
3653 | case X86::BI__builtin_ia32_vec_ext_v2si: |
3654 | case X86::BI__builtin_ia32_vec_ext_v2di: |
3655 | case X86::BI__builtin_ia32_vextractf128_pd256: |
3656 | case X86::BI__builtin_ia32_vextractf128_ps256: |
3657 | case X86::BI__builtin_ia32_vextractf128_si256: |
3658 | case X86::BI__builtin_ia32_extract128i256: |
3659 | case X86::BI__builtin_ia32_extractf64x4_mask: |
3660 | case X86::BI__builtin_ia32_extracti64x4_mask: |
3661 | case X86::BI__builtin_ia32_extractf32x8_mask: |
3662 | case X86::BI__builtin_ia32_extracti32x8_mask: |
3663 | case X86::BI__builtin_ia32_extractf64x2_256_mask: |
3664 | case X86::BI__builtin_ia32_extracti64x2_256_mask: |
3665 | case X86::BI__builtin_ia32_extractf32x4_256_mask: |
3666 | case X86::BI__builtin_ia32_extracti32x4_256_mask: |
3667 | i = 1; l = 0; u = 1; |
3668 | break; |
3669 | case X86::BI__builtin_ia32_vec_set_v2di: |
3670 | case X86::BI__builtin_ia32_vinsertf128_pd256: |
3671 | case X86::BI__builtin_ia32_vinsertf128_ps256: |
3672 | case X86::BI__builtin_ia32_vinsertf128_si256: |
3673 | case X86::BI__builtin_ia32_insert128i256: |
3674 | case X86::BI__builtin_ia32_insertf32x8: |
3675 | case X86::BI__builtin_ia32_inserti32x8: |
3676 | case X86::BI__builtin_ia32_insertf64x4: |
3677 | case X86::BI__builtin_ia32_inserti64x4: |
3678 | case X86::BI__builtin_ia32_insertf64x2_256: |
3679 | case X86::BI__builtin_ia32_inserti64x2_256: |
3680 | case X86::BI__builtin_ia32_insertf32x4_256: |
3681 | case X86::BI__builtin_ia32_inserti32x4_256: |
3682 | i = 2; l = 0; u = 1; |
3683 | break; |
3684 | case X86::BI__builtin_ia32_vpermilpd: |
3685 | case X86::BI__builtin_ia32_vec_ext_v4hi: |
3686 | case X86::BI__builtin_ia32_vec_ext_v4si: |
3687 | case X86::BI__builtin_ia32_vec_ext_v4sf: |
3688 | case X86::BI__builtin_ia32_vec_ext_v4di: |
3689 | case X86::BI__builtin_ia32_extractf32x4_mask: |
3690 | case X86::BI__builtin_ia32_extracti32x4_mask: |
3691 | case X86::BI__builtin_ia32_extractf64x2_512_mask: |
3692 | case X86::BI__builtin_ia32_extracti64x2_512_mask: |
3693 | i = 1; l = 0; u = 3; |
3694 | break; |
3695 | case X86::BI_mm_prefetch: |
3696 | case X86::BI__builtin_ia32_vec_ext_v8hi: |
3697 | case X86::BI__builtin_ia32_vec_ext_v8si: |
3698 | i = 1; l = 0; u = 7; |
3699 | break; |
3700 | case X86::BI__builtin_ia32_sha1rnds4: |
3701 | case X86::BI__builtin_ia32_blendpd: |
3702 | case X86::BI__builtin_ia32_shufpd: |
3703 | case X86::BI__builtin_ia32_vec_set_v4hi: |
3704 | case X86::BI__builtin_ia32_vec_set_v4si: |
3705 | case X86::BI__builtin_ia32_vec_set_v4di: |
3706 | case X86::BI__builtin_ia32_shuf_f32x4_256: |
3707 | case X86::BI__builtin_ia32_shuf_f64x2_256: |
3708 | case X86::BI__builtin_ia32_shuf_i32x4_256: |
3709 | case X86::BI__builtin_ia32_shuf_i64x2_256: |
3710 | case X86::BI__builtin_ia32_insertf64x2_512: |
3711 | case X86::BI__builtin_ia32_inserti64x2_512: |
3712 | case X86::BI__builtin_ia32_insertf32x4: |
3713 | case X86::BI__builtin_ia32_inserti32x4: |
3714 | i = 2; l = 0; u = 3; |
3715 | break; |
3716 | case X86::BI__builtin_ia32_vpermil2pd: |
3717 | case X86::BI__builtin_ia32_vpermil2pd256: |
3718 | case X86::BI__builtin_ia32_vpermil2ps: |
3719 | case X86::BI__builtin_ia32_vpermil2ps256: |
3720 | i = 3; l = 0; u = 3; |
3721 | break; |
3722 | case X86::BI__builtin_ia32_cmpb128_mask: |
3723 | case X86::BI__builtin_ia32_cmpw128_mask: |
3724 | case X86::BI__builtin_ia32_cmpd128_mask: |
3725 | case X86::BI__builtin_ia32_cmpq128_mask: |
3726 | case X86::BI__builtin_ia32_cmpb256_mask: |
3727 | case X86::BI__builtin_ia32_cmpw256_mask: |
3728 | case X86::BI__builtin_ia32_cmpd256_mask: |
3729 | case X86::BI__builtin_ia32_cmpq256_mask: |
3730 | case X86::BI__builtin_ia32_cmpb512_mask: |
3731 | case X86::BI__builtin_ia32_cmpw512_mask: |
3732 | case X86::BI__builtin_ia32_cmpd512_mask: |
3733 | case X86::BI__builtin_ia32_cmpq512_mask: |
3734 | case X86::BI__builtin_ia32_ucmpb128_mask: |
3735 | case X86::BI__builtin_ia32_ucmpw128_mask: |
3736 | case X86::BI__builtin_ia32_ucmpd128_mask: |
3737 | case X86::BI__builtin_ia32_ucmpq128_mask: |
3738 | case X86::BI__builtin_ia32_ucmpb256_mask: |
3739 | case X86::BI__builtin_ia32_ucmpw256_mask: |
3740 | case X86::BI__builtin_ia32_ucmpd256_mask: |
3741 | case X86::BI__builtin_ia32_ucmpq256_mask: |
3742 | case X86::BI__builtin_ia32_ucmpb512_mask: |
3743 | case X86::BI__builtin_ia32_ucmpw512_mask: |
3744 | case X86::BI__builtin_ia32_ucmpd512_mask: |
3745 | case X86::BI__builtin_ia32_ucmpq512_mask: |
3746 | case X86::BI__builtin_ia32_vpcomub: |
3747 | case X86::BI__builtin_ia32_vpcomuw: |
3748 | case X86::BI__builtin_ia32_vpcomud: |
3749 | case X86::BI__builtin_ia32_vpcomuq: |
3750 | case X86::BI__builtin_ia32_vpcomb: |
3751 | case X86::BI__builtin_ia32_vpcomw: |
3752 | case X86::BI__builtin_ia32_vpcomd: |
3753 | case X86::BI__builtin_ia32_vpcomq: |
3754 | case X86::BI__builtin_ia32_vec_set_v8hi: |
3755 | case X86::BI__builtin_ia32_vec_set_v8si: |
3756 | i = 2; l = 0; u = 7; |
3757 | break; |
3758 | case X86::BI__builtin_ia32_vpermilpd256: |
3759 | case X86::BI__builtin_ia32_roundps: |
3760 | case X86::BI__builtin_ia32_roundpd: |
3761 | case X86::BI__builtin_ia32_roundps256: |
3762 | case X86::BI__builtin_ia32_roundpd256: |
3763 | case X86::BI__builtin_ia32_getmantpd128_mask: |
3764 | case X86::BI__builtin_ia32_getmantpd256_mask: |
3765 | case X86::BI__builtin_ia32_getmantps128_mask: |
3766 | case X86::BI__builtin_ia32_getmantps256_mask: |
3767 | case X86::BI__builtin_ia32_getmantpd512_mask: |
3768 | case X86::BI__builtin_ia32_getmantps512_mask: |
3769 | case X86::BI__builtin_ia32_vec_ext_v16qi: |
3770 | case X86::BI__builtin_ia32_vec_ext_v16hi: |
3771 | i = 1; l = 0; u = 15; |
3772 | break; |
3773 | case X86::BI__builtin_ia32_pblendd128: |
3774 | case X86::BI__builtin_ia32_blendps: |
3775 | case X86::BI__builtin_ia32_blendpd256: |
3776 | case X86::BI__builtin_ia32_shufpd256: |
3777 | case X86::BI__builtin_ia32_roundss: |
3778 | case X86::BI__builtin_ia32_roundsd: |
3779 | case X86::BI__builtin_ia32_rangepd128_mask: |
3780 | case X86::BI__builtin_ia32_rangepd256_mask: |
3781 | case X86::BI__builtin_ia32_rangepd512_mask: |
3782 | case X86::BI__builtin_ia32_rangeps128_mask: |
3783 | case X86::BI__builtin_ia32_rangeps256_mask: |
3784 | case X86::BI__builtin_ia32_rangeps512_mask: |
3785 | case X86::BI__builtin_ia32_getmantsd_round_mask: |
3786 | case X86::BI__builtin_ia32_getmantss_round_mask: |
3787 | case X86::BI__builtin_ia32_vec_set_v16qi: |
3788 | case X86::BI__builtin_ia32_vec_set_v16hi: |
3789 | i = 2; l = 0; u = 15; |
3790 | break; |
3791 | case X86::BI__builtin_ia32_vec_ext_v32qi: |
3792 | i = 1; l = 0; u = 31; |
3793 | break; |
3794 | case X86::BI__builtin_ia32_cmpps: |
3795 | case X86::BI__builtin_ia32_cmpss: |
3796 | case X86::BI__builtin_ia32_cmppd: |
3797 | case X86::BI__builtin_ia32_cmpsd: |
3798 | case X86::BI__builtin_ia32_cmpps256: |
3799 | case X86::BI__builtin_ia32_cmppd256: |
3800 | case X86::BI__builtin_ia32_cmpps128_mask: |
3801 | case X86::BI__builtin_ia32_cmppd128_mask: |
3802 | case X86::BI__builtin_ia32_cmpps256_mask: |
3803 | case X86::BI__builtin_ia32_cmppd256_mask: |
3804 | case X86::BI__builtin_ia32_cmpps512_mask: |
3805 | case X86::BI__builtin_ia32_cmppd512_mask: |
3806 | case X86::BI__builtin_ia32_cmpsd_mask: |
3807 | case X86::BI__builtin_ia32_cmpss_mask: |
3808 | case X86::BI__builtin_ia32_vec_set_v32qi: |
3809 | i = 2; l = 0; u = 31; |
3810 | break; |
3811 | case X86::BI__builtin_ia32_permdf256: |
3812 | case X86::BI__builtin_ia32_permdi256: |
3813 | case X86::BI__builtin_ia32_permdf512: |
3814 | case X86::BI__builtin_ia32_permdi512: |
3815 | case X86::BI__builtin_ia32_vpermilps: |
3816 | case X86::BI__builtin_ia32_vpermilps256: |
3817 | case X86::BI__builtin_ia32_vpermilpd512: |
3818 | case X86::BI__builtin_ia32_vpermilps512: |
3819 | case X86::BI__builtin_ia32_pshufd: |
3820 | case X86::BI__builtin_ia32_pshufd256: |
3821 | case X86::BI__builtin_ia32_pshufd512: |
3822 | case X86::BI__builtin_ia32_pshufhw: |
3823 | case X86::BI__builtin_ia32_pshufhw256: |
3824 | case X86::BI__builtin_ia32_pshufhw512: |
3825 | case X86::BI__builtin_ia32_pshuflw: |
3826 | case X86::BI__builtin_ia32_pshuflw256: |
3827 | case X86::BI__builtin_ia32_pshuflw512: |
3828 | case X86::BI__builtin_ia32_vcvtps2ph: |
3829 | case X86::BI__builtin_ia32_vcvtps2ph_mask: |
3830 | case X86::BI__builtin_ia32_vcvtps2ph256: |
3831 | case X86::BI__builtin_ia32_vcvtps2ph256_mask: |
3832 | case X86::BI__builtin_ia32_vcvtps2ph512_mask: |
3833 | case X86::BI__builtin_ia32_rndscaleps_128_mask: |
3834 | case X86::BI__builtin_ia32_rndscalepd_128_mask: |
3835 | case X86::BI__builtin_ia32_rndscaleps_256_mask: |
3836 | case X86::BI__builtin_ia32_rndscalepd_256_mask: |
3837 | case X86::BI__builtin_ia32_rndscaleps_mask: |
3838 | case X86::BI__builtin_ia32_rndscalepd_mask: |
3839 | case X86::BI__builtin_ia32_reducepd128_mask: |
3840 | case X86::BI__builtin_ia32_reducepd256_mask: |
3841 | case X86::BI__builtin_ia32_reducepd512_mask: |
3842 | case X86::BI__builtin_ia32_reduceps128_mask: |
3843 | case X86::BI__builtin_ia32_reduceps256_mask: |
3844 | case X86::BI__builtin_ia32_reduceps512_mask: |
3845 | case X86::BI__builtin_ia32_prold512: |
3846 | case X86::BI__builtin_ia32_prolq512: |
3847 | case X86::BI__builtin_ia32_prold128: |
3848 | case X86::BI__builtin_ia32_prold256: |
3849 | case X86::BI__builtin_ia32_prolq128: |
3850 | case X86::BI__builtin_ia32_prolq256: |
3851 | case X86::BI__builtin_ia32_prord512: |
3852 | case X86::BI__builtin_ia32_prorq512: |
3853 | case X86::BI__builtin_ia32_prord128: |
3854 | case X86::BI__builtin_ia32_prord256: |
3855 | case X86::BI__builtin_ia32_prorq128: |
3856 | case X86::BI__builtin_ia32_prorq256: |
3857 | case X86::BI__builtin_ia32_fpclasspd128_mask: |
3858 | case X86::BI__builtin_ia32_fpclasspd256_mask: |
3859 | case X86::BI__builtin_ia32_fpclassps128_mask: |
3860 | case X86::BI__builtin_ia32_fpclassps256_mask: |
3861 | case X86::BI__builtin_ia32_fpclassps512_mask: |
3862 | case X86::BI__builtin_ia32_fpclasspd512_mask: |
3863 | case X86::BI__builtin_ia32_fpclasssd_mask: |
3864 | case X86::BI__builtin_ia32_fpclassss_mask: |
3865 | case X86::BI__builtin_ia32_pslldqi128_byteshift: |
3866 | case X86::BI__builtin_ia32_pslldqi256_byteshift: |
3867 | case X86::BI__builtin_ia32_pslldqi512_byteshift: |
3868 | case X86::BI__builtin_ia32_psrldqi128_byteshift: |
3869 | case X86::BI__builtin_ia32_psrldqi256_byteshift: |
3870 | case X86::BI__builtin_ia32_psrldqi512_byteshift: |
3871 | case X86::BI__builtin_ia32_kshiftliqi: |
3872 | case X86::BI__builtin_ia32_kshiftlihi: |
3873 | case X86::BI__builtin_ia32_kshiftlisi: |
3874 | case X86::BI__builtin_ia32_kshiftlidi: |
3875 | case X86::BI__builtin_ia32_kshiftriqi: |
3876 | case X86::BI__builtin_ia32_kshiftrihi: |
3877 | case X86::BI__builtin_ia32_kshiftrisi: |
3878 | case X86::BI__builtin_ia32_kshiftridi: |
3879 | i = 1; l = 0; u = 255; |
3880 | break; |
3881 | case X86::BI__builtin_ia32_vperm2f128_pd256: |
3882 | case X86::BI__builtin_ia32_vperm2f128_ps256: |
3883 | case X86::BI__builtin_ia32_vperm2f128_si256: |
3884 | case X86::BI__builtin_ia32_permti256: |
3885 | case X86::BI__builtin_ia32_pblendw128: |
3886 | case X86::BI__builtin_ia32_pblendw256: |
3887 | case X86::BI__builtin_ia32_blendps256: |
3888 | case X86::BI__builtin_ia32_pblendd256: |
3889 | case X86::BI__builtin_ia32_palignr128: |
3890 | case X86::BI__builtin_ia32_palignr256: |
3891 | case X86::BI__builtin_ia32_palignr512: |
3892 | case X86::BI__builtin_ia32_alignq512: |
3893 | case X86::BI__builtin_ia32_alignd512: |
3894 | case X86::BI__builtin_ia32_alignd128: |
3895 | case X86::BI__builtin_ia32_alignd256: |
3896 | case X86::BI__builtin_ia32_alignq128: |
3897 | case X86::BI__builtin_ia32_alignq256: |
3898 | case X86::BI__builtin_ia32_vcomisd: |
3899 | case X86::BI__builtin_ia32_vcomiss: |
3900 | case X86::BI__builtin_ia32_shuf_f32x4: |
3901 | case X86::BI__builtin_ia32_shuf_f64x2: |
3902 | case X86::BI__builtin_ia32_shuf_i32x4: |
3903 | case X86::BI__builtin_ia32_shuf_i64x2: |
3904 | case X86::BI__builtin_ia32_shufpd512: |
3905 | case X86::BI__builtin_ia32_shufps: |
3906 | case X86::BI__builtin_ia32_shufps256: |
3907 | case X86::BI__builtin_ia32_shufps512: |
3908 | case X86::BI__builtin_ia32_dbpsadbw128: |
3909 | case X86::BI__builtin_ia32_dbpsadbw256: |
3910 | case X86::BI__builtin_ia32_dbpsadbw512: |
3911 | case X86::BI__builtin_ia32_vpshldd128: |
3912 | case X86::BI__builtin_ia32_vpshldd256: |
3913 | case X86::BI__builtin_ia32_vpshldd512: |
3914 | case X86::BI__builtin_ia32_vpshldq128: |
3915 | case X86::BI__builtin_ia32_vpshldq256: |
3916 | case X86::BI__builtin_ia32_vpshldq512: |
3917 | case X86::BI__builtin_ia32_vpshldw128: |
3918 | case X86::BI__builtin_ia32_vpshldw256: |
3919 | case X86::BI__builtin_ia32_vpshldw512: |
3920 | case X86::BI__builtin_ia32_vpshrdd128: |
3921 | case X86::BI__builtin_ia32_vpshrdd256: |
3922 | case X86::BI__builtin_ia32_vpshrdd512: |
3923 | case X86::BI__builtin_ia32_vpshrdq128: |
3924 | case X86::BI__builtin_ia32_vpshrdq256: |
3925 | case X86::BI__builtin_ia32_vpshrdq512: |
3926 | case X86::BI__builtin_ia32_vpshrdw128: |
3927 | case X86::BI__builtin_ia32_vpshrdw256: |
3928 | case X86::BI__builtin_ia32_vpshrdw512: |
3929 | i = 2; l = 0; u = 255; |
3930 | break; |
3931 | case X86::BI__builtin_ia32_fixupimmpd512_mask: |
3932 | case X86::BI__builtin_ia32_fixupimmpd512_maskz: |
3933 | case X86::BI__builtin_ia32_fixupimmps512_mask: |
3934 | case X86::BI__builtin_ia32_fixupimmps512_maskz: |
3935 | case X86::BI__builtin_ia32_fixupimmsd_mask: |
3936 | case X86::BI__builtin_ia32_fixupimmsd_maskz: |
3937 | case X86::BI__builtin_ia32_fixupimmss_mask: |
3938 | case X86::BI__builtin_ia32_fixupimmss_maskz: |
3939 | case X86::BI__builtin_ia32_fixupimmpd128_mask: |
3940 | case X86::BI__builtin_ia32_fixupimmpd128_maskz: |
3941 | case X86::BI__builtin_ia32_fixupimmpd256_mask: |
3942 | case X86::BI__builtin_ia32_fixupimmpd256_maskz: |
3943 | case X86::BI__builtin_ia32_fixupimmps128_mask: |
3944 | case X86::BI__builtin_ia32_fixupimmps128_maskz: |
3945 | case X86::BI__builtin_ia32_fixupimmps256_mask: |
3946 | case X86::BI__builtin_ia32_fixupimmps256_maskz: |
3947 | case X86::BI__builtin_ia32_pternlogd512_mask: |
3948 | case X86::BI__builtin_ia32_pternlogd512_maskz: |
3949 | case X86::BI__builtin_ia32_pternlogq512_mask: |
3950 | case X86::BI__builtin_ia32_pternlogq512_maskz: |
3951 | case X86::BI__builtin_ia32_pternlogd128_mask: |
3952 | case X86::BI__builtin_ia32_pternlogd128_maskz: |
3953 | case X86::BI__builtin_ia32_pternlogd256_mask: |
3954 | case X86::BI__builtin_ia32_pternlogd256_maskz: |
3955 | case X86::BI__builtin_ia32_pternlogq128_mask: |
3956 | case X86::BI__builtin_ia32_pternlogq128_maskz: |
3957 | case X86::BI__builtin_ia32_pternlogq256_mask: |
3958 | case X86::BI__builtin_ia32_pternlogq256_maskz: |
3959 | i = 3; l = 0; u = 255; |
3960 | break; |
3961 | case X86::BI__builtin_ia32_gatherpfdpd: |
3962 | case X86::BI__builtin_ia32_gatherpfdps: |
3963 | case X86::BI__builtin_ia32_gatherpfqpd: |
3964 | case X86::BI__builtin_ia32_gatherpfqps: |
3965 | case X86::BI__builtin_ia32_scatterpfdpd: |
3966 | case X86::BI__builtin_ia32_scatterpfdps: |
3967 | case X86::BI__builtin_ia32_scatterpfqpd: |
3968 | case X86::BI__builtin_ia32_scatterpfqps: |
3969 | i = 4; l = 2; u = 3; |
3970 | break; |
3971 | case X86::BI__builtin_ia32_rndscalesd_round_mask: |
3972 | case X86::BI__builtin_ia32_rndscaless_round_mask: |
3973 | i = 4; l = 0; u = 255; |
3974 | break; |
3975 | } |
3976 | |
3977 | |
3978 | |
3979 | |
3980 | |
3981 | return SemaBuiltinConstantArgRange(TheCall, i, l, u, false); |
3982 | } |
3983 | |
3984 | |
3985 | |
3986 | |
3987 | |
3988 | bool Sema::getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, |
3989 | FormatStringInfo *FSI) { |
3990 | FSI->HasVAListArg = Format->getFirstArg() == 0; |
3991 | FSI->FormatIdx = Format->getFormatIdx() - 1; |
3992 | FSI->FirstDataArg = FSI->HasVAListArg ? 0 : Format->getFirstArg() - 1; |
3993 | |
3994 | |
3995 | |
3996 | |
3997 | if (IsCXXMember) { |
3998 | if(FSI->FormatIdx == 0) |
3999 | return false; |
4000 | --FSI->FormatIdx; |
4001 | if (FSI->FirstDataArg != 0) |
4002 | --FSI->FirstDataArg; |
4003 | } |
4004 | return true; |
4005 | } |
4006 | |
4007 | |
4008 | |
4009 | |
4010 | static bool CheckNonNullExpr(Sema &S, const Expr *Expr) { |
4011 | |
4012 | if (auto nullability |
4013 | = Expr->IgnoreImplicit()->getType()->getNullability(S.Context)) { |
4014 | if (*nullability == NullabilityKind::NonNull) |
4015 | return false; |
4016 | } |
4017 | |
4018 | |
4019 | |
4020 | if (const RecordType *UT = Expr->getType()->getAsUnionType()) { |
4021 | if (UT->getDecl()->hasAttr<TransparentUnionAttr>()) |
4022 | if (const CompoundLiteralExpr *CLE = |
4023 | dyn_cast<CompoundLiteralExpr>(Expr)) |
4024 | if (const InitListExpr *ILE = |
4025 | dyn_cast<InitListExpr>(CLE->getInitializer())) |
4026 | Expr = ILE->getInit(0); |
4027 | } |
4028 | |
4029 | bool Result; |
4030 | return (!Expr->isValueDependent() && |
4031 | Expr->EvaluateAsBooleanCondition(Result, S.Context) && |
4032 | !Result); |
4033 | } |
4034 | |
4035 | static void CheckNonNullArgument(Sema &S, |
4036 | const Expr *ArgExpr, |
4037 | SourceLocation CallSiteLoc) { |
4038 | if (CheckNonNullExpr(S, ArgExpr)) |
4039 | S.DiagRuntimeBehavior(CallSiteLoc, ArgExpr, |
4040 | S.PDiag(diag::warn_null_arg) << ArgExpr->getSourceRange()); |
4041 | } |
4042 | |
4043 | bool Sema::GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx) { |
4044 | FormatStringInfo FSI; |
4045 | if ((GetFormatStringType(Format) == FST_NSString) && |
4046 | getFormatStringInfo(Format, false, &FSI)) { |
4047 | Idx = FSI.FormatIdx; |
4048 | return true; |
4049 | } |
4050 | return false; |
4051 | } |
4052 | |
4053 | |
4054 | |
4055 | static void |
4056 | DiagnoseCStringFormatDirectiveInCFAPI(Sema &S, |
4057 | const NamedDecl *FDecl, |
4058 | Expr **Args, |
4059 | unsigned NumArgs) { |
4060 | unsigned Idx = 0; |
4061 | bool Format = false; |
4062 | ObjCStringFormatFamily SFFamily = FDecl->getObjCFStringFormattingFamily(); |
4063 | if (SFFamily == ObjCStringFormatFamily::SFF_CFString) { |
4064 | Idx = 2; |
4065 | Format = true; |
4066 | } |
4067 | else |
4068 | for (const auto *I : FDecl->specific_attrs<FormatAttr>()) { |
4069 | if (S.GetFormatNSStringIdx(I, Idx)) { |
4070 | Format = true; |
4071 | break; |
4072 | } |
4073 | } |
4074 | if (!Format || NumArgs <= Idx) |
4075 | return; |
4076 | const Expr *FormatExpr = Args[Idx]; |
4077 | if (const CStyleCastExpr *CSCE = dyn_cast<CStyleCastExpr>(FormatExpr)) |
4078 | FormatExpr = CSCE->getSubExpr(); |
4079 | const StringLiteral *FormatString; |
4080 | if (const ObjCStringLiteral *OSL = |
4081 | dyn_cast<ObjCStringLiteral>(FormatExpr->IgnoreParenImpCasts())) |
4082 | FormatString = OSL->getString(); |
4083 | else |
4084 | FormatString = dyn_cast<StringLiteral>(FormatExpr->IgnoreParenImpCasts()); |
4085 | if (!FormatString) |
4086 | return; |
4087 | if (S.FormatStringHasSArg(FormatString)) { |
4088 | S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string) |
4089 | << "%s" << 1 << 1; |
4090 | S.Diag(FDecl->getLocation(), diag::note_entity_declared_at) |
4091 | << FDecl->getDeclName(); |
4092 | } |
4093 | } |
4094 | |
4095 | |
4096 | static bool isNonNullType(ASTContext &ctx, QualType type) { |
4097 | if (auto nullability = type->getNullability(ctx)) |
4098 | return *nullability == NullabilityKind::NonNull; |
4099 | |
4100 | return false; |
4101 | } |
4102 | |
4103 | static void CheckNonNullArguments(Sema &S, |
4104 | const NamedDecl *FDecl, |
4105 | const FunctionProtoType *Proto, |
4106 | ArrayRef<const Expr *> Args, |
4107 | SourceLocation CallSiteLoc) { |
4108 | (0) . __assert_fail ("(FDecl || Proto) && \"Need a function declaration or prototype\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 4108, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((FDecl || Proto) && "Need a function declaration or prototype"); |
4109 | |
4110 | |
4111 | llvm::SmallBitVector NonNullArgs; |
4112 | if (FDecl) { |
4113 | |
4114 | for (const auto *NonNull : FDecl->specific_attrs<NonNullAttr>()) { |
4115 | if (!NonNull->args_size()) { |
4116 | |
4117 | for (const auto *Arg : Args) |
4118 | if (S.isValidPointerAttrType(Arg->getType())) |
4119 | CheckNonNullArgument(S, Arg, CallSiteLoc); |
4120 | return; |
4121 | } |
4122 | |
4123 | for (const ParamIdx &Idx : NonNull->args()) { |
4124 | unsigned IdxAST = Idx.getASTIndex(); |
4125 | if (IdxAST >= Args.size()) |
4126 | continue; |
4127 | if (NonNullArgs.empty()) |
4128 | NonNullArgs.resize(Args.size()); |
4129 | NonNullArgs.set(IdxAST); |
4130 | } |
4131 | } |
4132 | } |
4133 | |
4134 | if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) { |
4135 | |
4136 | |
4137 | ArrayRef<ParmVarDecl*> parms; |
4138 | if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl)) |
4139 | parms = FD->parameters(); |
4140 | else |
4141 | parms = cast<ObjCMethodDecl>(FDecl)->parameters(); |
4142 | |
4143 | unsigned ParamIndex = 0; |
4144 | for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end(); |
4145 | I != E; ++I, ++ParamIndex) { |
4146 | const ParmVarDecl *PVD = *I; |
4147 | if (PVD->hasAttr<NonNullAttr>() || |
4148 | isNonNullType(S.Context, PVD->getType())) { |
4149 | if (NonNullArgs.empty()) |
4150 | NonNullArgs.resize(Args.size()); |
4151 | |
4152 | NonNullArgs.set(ParamIndex); |
4153 | } |
4154 | } |
4155 | } else { |
4156 | |
4157 | |
4158 | if (!Proto) { |
4159 | if (const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) { |
4160 | QualType type = VD->getType().getNonReferenceType(); |
4161 | if (auto pointerType = type->getAs<PointerType>()) |
4162 | type = pointerType->getPointeeType(); |
4163 | else if (auto blockType = type->getAs<BlockPointerType>()) |
4164 | type = blockType->getPointeeType(); |
4165 | |
4166 | |
4167 | |
4168 | Proto = type->getAs<FunctionProtoType>(); |
4169 | } |
4170 | } |
4171 | |
4172 | |
4173 | |
4174 | if (Proto) { |
4175 | unsigned Index = 0; |
4176 | for (auto paramType : Proto->getParamTypes()) { |
4177 | if (isNonNullType(S.Context, paramType)) { |
4178 | if (NonNullArgs.empty()) |
4179 | NonNullArgs.resize(Args.size()); |
4180 | |
4181 | NonNullArgs.set(Index); |
4182 | } |
4183 | |
4184 | ++Index; |
4185 | } |
4186 | } |
4187 | } |
4188 | |
4189 | |
4190 | for (unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size(); |
4191 | ArgIndex != ArgIndexEnd; ++ArgIndex) { |
4192 | if (NonNullArgs[ArgIndex]) |
4193 | CheckNonNullArgument(S, Args[ArgIndex], CallSiteLoc); |
4194 | } |
4195 | } |
4196 | |
4197 | |
4198 | |
4199 | |
4200 | void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, |
4201 | const Expr *ThisArg, ArrayRef<const Expr *> Args, |
4202 | bool IsMemberFunction, SourceLocation Loc, |
4203 | SourceRange Range, VariadicCallType CallType) { |
4204 | |
4205 | if (CurContext->isDependentContext()) |
4206 | return; |
4207 | |
4208 | |
4209 | llvm::SmallBitVector CheckedVarArgs; |
4210 | if (FDecl) { |
4211 | for (const auto *I : FDecl->specific_attrs<FormatAttr>()) { |
4212 | |
4213 | CheckedVarArgs.resize(Args.size()); |
4214 | |
4215 | CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range, |
4216 | CheckedVarArgs); |
4217 | } |
4218 | } |
4219 | |
4220 | |
4221 | |
4222 | auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl); |
4223 | if (CallType != VariadicDoesNotApply && |
4224 | (!FD || FD->getBuiltinID() != Builtin::BI__noop)) { |
4225 | unsigned NumParams = Proto ? Proto->getNumParams() |
4226 | : FDecl && isa<FunctionDecl>(FDecl) |
4227 | ? cast<FunctionDecl>(FDecl)->getNumParams() |
4228 | : FDecl && isa<ObjCMethodDecl>(FDecl) |
4229 | ? cast<ObjCMethodDecl>(FDecl)->param_size() |
4230 | : 0; |
4231 | |
4232 | for (unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) { |
4233 | |
4234 | if (const Expr *Arg = Args[ArgIdx]) { |
4235 | if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx]) |
4236 | checkVariadicArgument(Arg, CallType); |
4237 | } |
4238 | } |
4239 | } |
4240 | |
4241 | if (FDecl || Proto) { |
4242 | CheckNonNullArguments(*this, FDecl, Proto, Args, Loc); |
4243 | |
4244 | |
4245 | if (FDecl) { |
4246 | for (const auto *I : FDecl->specific_attrs<ArgumentWithTypeTagAttr>()) |
4247 | CheckArgumentWithTypeTag(I, Args, Loc); |
4248 | } |
4249 | } |
4250 | |
4251 | if (FD) |
4252 | diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc); |
4253 | } |
4254 | |
4255 | |
4256 | |
4257 | void Sema::CheckConstructorCall(FunctionDecl *FDecl, |
4258 | ArrayRef<const Expr *> Args, |
4259 | const FunctionProtoType *Proto, |
4260 | SourceLocation Loc) { |
4261 | VariadicCallType CallType = |
4262 | Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply; |
4263 | checkCall(FDecl, Proto, , Args, , |
4264 | Loc, SourceRange(), CallType); |
4265 | } |
4266 | |
4267 | |
4268 | |
4269 | bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, |
4270 | const FunctionProtoType *Proto) { |
4271 | bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) && |
4272 | isa<CXXMethodDecl>(FDecl); |
4273 | bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) || |
4274 | IsMemberOperatorCall; |
4275 | VariadicCallType CallType = getVariadicCallType(FDecl, Proto, |
4276 | TheCall->getCallee()); |
4277 | Expr** Args = TheCall->getArgs(); |
4278 | unsigned NumArgs = TheCall->getNumArgs(); |
4279 | |
4280 | Expr *ImplicitThis = nullptr; |
4281 | if (IsMemberOperatorCall) { |
4282 | |
4283 | |
4284 | |
4285 | ImplicitThis = Args[0]; |
4286 | ++Args; |
4287 | --NumArgs; |
4288 | } else if (IsMemberFunction) |
4289 | ImplicitThis = |
4290 | cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument(); |
4291 | |
4292 | checkCall(FDecl, Proto, ImplicitThis, llvm::makeArrayRef(Args, NumArgs), |
4293 | IsMemberFunction, TheCall->getRParenLoc(), |
4294 | TheCall->getCallee()->getSourceRange(), CallType); |
4295 | |
4296 | IdentifierInfo *FnInfo = FDecl->getIdentifier(); |
4297 | |
4298 | |
4299 | if (!FnInfo) |
4300 | return false; |
4301 | |
4302 | CheckAbsoluteValueFunction(TheCall, FDecl); |
4303 | CheckMaxUnsignedZero(TheCall, FDecl); |
4304 | |
4305 | if (getLangOpts().ObjC) |
4306 | DiagnoseCStringFormatDirectiveInCFAPI(*this, FDecl, Args, NumArgs); |
4307 | |
4308 | unsigned CMId = FDecl->getMemoryFunctionKind(); |
4309 | if (CMId == 0) |
4310 | return false; |
4311 | |
4312 | |
4313 | if (CMId == Builtin::BIstrlcpy || CMId == Builtin::BIstrlcat) |
4314 | CheckStrlcpycatArguments(TheCall, FnInfo); |
4315 | else if (CMId == Builtin::BIstrncat) |
4316 | CheckStrncatArguments(TheCall, FnInfo); |
4317 | else |
4318 | CheckMemaccessArguments(TheCall, CMId, FnInfo); |
4319 | |
4320 | return false; |
4321 | } |
4322 | |
4323 | bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, |
4324 | ArrayRef<const Expr *> Args) { |
4325 | VariadicCallType CallType = |
4326 | Method->isVariadic() ? VariadicMethod : VariadicDoesNotApply; |
4327 | |
4328 | checkCall(Method, nullptr, , Args, |
4329 | , lbrac, Method->getSourceRange(), |
4330 | CallType); |
4331 | |
4332 | return false; |
4333 | } |
4334 | |
4335 | bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, |
4336 | const FunctionProtoType *Proto) { |
4337 | QualType Ty; |
4338 | if (const auto *V = dyn_cast<VarDecl>(NDecl)) |
4339 | Ty = V->getType().getNonReferenceType(); |
4340 | else if (const auto *F = dyn_cast<FieldDecl>(NDecl)) |
4341 | Ty = F->getType().getNonReferenceType(); |
4342 | else |
4343 | return false; |
4344 | |
4345 | if (!Ty->isBlockPointerType() && !Ty->isFunctionPointerType() && |
4346 | !Ty->isFunctionProtoType()) |
4347 | return false; |
4348 | |
4349 | VariadicCallType CallType; |
4350 | if (!Proto || !Proto->isVariadic()) { |
4351 | CallType = VariadicDoesNotApply; |
4352 | } else if (Ty->isBlockPointerType()) { |
4353 | CallType = VariadicBlock; |
4354 | } else { |
4355 | CallType = VariadicFunction; |
4356 | } |
4357 | |
4358 | checkCall(NDecl, Proto, , |
4359 | llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()), |
4360 | , TheCall->getRParenLoc(), |
4361 | TheCall->getCallee()->getSourceRange(), CallType); |
4362 | |
4363 | return false; |
4364 | } |
4365 | |
4366 | |
4367 | |
4368 | bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) { |
4369 | VariadicCallType CallType = getVariadicCallType(, Proto, |
4370 | TheCall->getCallee()); |
4371 | checkCall(, Proto, , |
4372 | llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()), |
4373 | , TheCall->getRParenLoc(), |
4374 | TheCall->getCallee()->getSourceRange(), CallType); |
4375 | |
4376 | return false; |
4377 | } |
4378 | |
4379 | static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) { |
4380 | if (!llvm::isValidAtomicOrderingCABI(Ordering)) |
4381 | return false; |
4382 | |
4383 | auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering; |
4384 | switch (Op) { |
4385 | case AtomicExpr::AO__c11_atomic_init: |
4386 | case AtomicExpr::AO__opencl_atomic_init: |
4387 | llvm_unreachable("There is no ordering argument for an init"); |
4388 | |
4389 | case AtomicExpr::AO__c11_atomic_load: |
4390 | case AtomicExpr::AO__opencl_atomic_load: |
4391 | case AtomicExpr::AO__atomic_load_n: |
4392 | case AtomicExpr::AO__atomic_load: |
4393 | return OrderingCABI != llvm::AtomicOrderingCABI::release && |
4394 | OrderingCABI != llvm::AtomicOrderingCABI::acq_rel; |
4395 | |
4396 | case AtomicExpr::AO__c11_atomic_store: |
4397 | case AtomicExpr::AO__opencl_atomic_store: |
4398 | case AtomicExpr::AO__atomic_store: |
4399 | case AtomicExpr::AO__atomic_store_n: |
4400 | return OrderingCABI != llvm::AtomicOrderingCABI::consume && |
4401 | OrderingCABI != llvm::AtomicOrderingCABI::acquire && |
4402 | OrderingCABI != llvm::AtomicOrderingCABI::acq_rel; |
4403 | |
4404 | default: |
4405 | return true; |
4406 | } |
4407 | } |
4408 | |
4409 | ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, |
4410 | AtomicExpr::AtomicOp Op) { |
4411 | CallExpr *TheCall = cast<CallExpr>(TheCallResult.get()); |
4412 | DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); |
4413 | |
4414 | |
4415 | |
4416 | |
4417 | enum { |
4418 | |
4419 | Init, |
4420 | |
4421 | |
4422 | Load, |
4423 | |
4424 | |
4425 | LoadCopy, |
4426 | |
4427 | |
4428 | Copy, |
4429 | |
4430 | |
4431 | Arithmetic, |
4432 | |
4433 | |
4434 | Xchg, |
4435 | |
4436 | |
4437 | GNUXchg, |
4438 | |
4439 | |
4440 | C11CmpXchg, |
4441 | |
4442 | |
4443 | GNUCmpXchg |
4444 | } Form = Init; |
4445 | |
4446 | const unsigned NumForm = GNUCmpXchg + 1; |
4447 | const unsigned NumArgs[] = { 2, 2, 3, 3, 3, 3, 4, 5, 6 }; |
4448 | const unsigned NumVals[] = { 1, 0, 1, 1, 1, 1, 2, 2, 3 }; |
4449 | |
4450 | |
4451 | |
4452 | |
4453 | |
4454 | |
4455 | |
4456 | static_assert(sizeof(NumArgs)/sizeof(NumArgs[0]) == NumForm |
4457 | && sizeof(NumVals)/sizeof(NumVals[0]) == NumForm, |
4458 | "need to update code for modified forms"); |
4459 | static_assert(AtomicExpr::AO__c11_atomic_init == 0 && |
4460 | AtomicExpr::AO__c11_atomic_fetch_xor + 1 == |
4461 | AtomicExpr::AO__atomic_load, |
4462 | "need to update code for modified C11 atomics"); |
4463 | bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_init && |
4464 | Op <= AtomicExpr::AO__opencl_atomic_fetch_max; |
4465 | bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_init && |
4466 | Op <= AtomicExpr::AO__c11_atomic_fetch_xor) || |
4467 | IsOpenCL; |
4468 | bool IsN = Op == AtomicExpr::AO__atomic_load_n || |
4469 | Op == AtomicExpr::AO__atomic_store_n || |
4470 | Op == AtomicExpr::AO__atomic_exchange_n || |
4471 | Op == AtomicExpr::AO__atomic_compare_exchange_n; |
4472 | bool IsAddSub = false; |
4473 | bool IsMinMax = false; |
4474 | |
4475 | switch (Op) { |
4476 | case AtomicExpr::AO__c11_atomic_init: |
4477 | case AtomicExpr::AO__opencl_atomic_init: |
4478 | Form = Init; |
4479 | break; |
4480 | |
4481 | case AtomicExpr::AO__c11_atomic_load: |
4482 | case AtomicExpr::AO__opencl_atomic_load: |
4483 | case AtomicExpr::AO__atomic_load_n: |
4484 | Form = Load; |
4485 | break; |
4486 | |
4487 | case AtomicExpr::AO__atomic_load: |
4488 | Form = LoadCopy; |
4489 | break; |
4490 | |
4491 | case AtomicExpr::AO__c11_atomic_store: |
4492 | case AtomicExpr::AO__opencl_atomic_store: |
4493 | case AtomicExpr::AO__atomic_store: |
4494 | case AtomicExpr::AO__atomic_store_n: |
4495 | Form = Copy; |
4496 | break; |
4497 | |
4498 | case AtomicExpr::AO__c11_atomic_fetch_add: |
4499 | case AtomicExpr::AO__c11_atomic_fetch_sub: |
4500 | case AtomicExpr::AO__opencl_atomic_fetch_add: |
4501 | case AtomicExpr::AO__opencl_atomic_fetch_sub: |
4502 | case AtomicExpr::AO__opencl_atomic_fetch_min: |
4503 | case AtomicExpr::AO__opencl_atomic_fetch_max: |
4504 | case AtomicExpr::AO__atomic_fetch_add: |
4505 | case AtomicExpr::AO__atomic_fetch_sub: |
4506 | case AtomicExpr::AO__atomic_add_fetch: |
4507 | case AtomicExpr::AO__atomic_sub_fetch: |
4508 | IsAddSub = true; |
4509 | LLVM_FALLTHROUGH; |
4510 | case AtomicExpr::AO__c11_atomic_fetch_and: |
4511 | case AtomicExpr::AO__c11_atomic_fetch_or: |
4512 | case AtomicExpr::AO__c11_atomic_fetch_xor: |
4513 | case AtomicExpr::AO__opencl_atomic_fetch_and: |
4514 | case AtomicExpr::AO__opencl_atomic_fetch_or: |
4515 | case AtomicExpr::AO__opencl_atomic_fetch_xor: |
4516 | case AtomicExpr::AO__atomic_fetch_and: |
4517 | case AtomicExpr::AO__atomic_fetch_or: |
4518 | case AtomicExpr::AO__atomic_fetch_xor: |
4519 | case AtomicExpr::AO__atomic_fetch_nand: |
4520 | case AtomicExpr::AO__atomic_and_fetch: |
4521 | case AtomicExpr::AO__atomic_or_fetch: |
4522 | case AtomicExpr::AO__atomic_xor_fetch: |
4523 | case AtomicExpr::AO__atomic_nand_fetch: |
4524 | Form = Arithmetic; |
4525 | break; |
4526 | |
4527 | case AtomicExpr::AO__atomic_fetch_min: |
4528 | case AtomicExpr::AO__atomic_fetch_max: |
4529 | IsMinMax = true; |
4530 | Form = Arithmetic; |
4531 | break; |
4532 | |
4533 | case AtomicExpr::AO__c11_atomic_exchange: |
4534 | case AtomicExpr::AO__opencl_atomic_exchange: |
4535 | case AtomicExpr::AO__atomic_exchange_n: |
4536 | Form = Xchg; |
4537 | break; |
4538 | |
4539 | case AtomicExpr::AO__atomic_exchange: |
4540 | Form = GNUXchg; |
4541 | break; |
4542 | |
4543 | case AtomicExpr::AO__c11_atomic_compare_exchange_strong: |
4544 | case AtomicExpr::AO__c11_atomic_compare_exchange_weak: |
4545 | case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: |
4546 | case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: |
4547 | Form = C11CmpXchg; |
4548 | break; |
4549 | |
4550 | case AtomicExpr::AO__atomic_compare_exchange: |
4551 | case AtomicExpr::AO__atomic_compare_exchange_n: |
4552 | Form = GNUCmpXchg; |
4553 | break; |
4554 | } |
4555 | |
4556 | unsigned AdjustedNumArgs = NumArgs[Form]; |
4557 | if (IsOpenCL && Op != AtomicExpr::AO__opencl_atomic_init) |
4558 | ++AdjustedNumArgs; |
4559 | |
4560 | if (TheCall->getNumArgs() < AdjustedNumArgs) { |
4561 | Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args) |
4562 | << 0 << AdjustedNumArgs << TheCall->getNumArgs() |
4563 | << TheCall->getCallee()->getSourceRange(); |
4564 | return ExprError(); |
4565 | } else if (TheCall->getNumArgs() > AdjustedNumArgs) { |
4566 | Diag(TheCall->getArg(AdjustedNumArgs)->getBeginLoc(), |
4567 | diag::err_typecheck_call_too_many_args) |
4568 | << 0 << AdjustedNumArgs << TheCall->getNumArgs() |
4569 | << TheCall->getCallee()->getSourceRange(); |
4570 | return ExprError(); |
4571 | } |
4572 | |
4573 | |
4574 | Expr *Ptr = TheCall->getArg(0); |
4575 | ExprResult ConvertedPtr = DefaultFunctionArrayLvalueConversion(Ptr); |
4576 | if (ConvertedPtr.isInvalid()) |
4577 | return ExprError(); |
4578 | |
4579 | Ptr = ConvertedPtr.get(); |
4580 | const PointerType *pointerType = Ptr->getType()->getAs<PointerType>(); |
4581 | if (!pointerType) { |
4582 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) |
4583 | << Ptr->getType() << Ptr->getSourceRange(); |
4584 | return ExprError(); |
4585 | } |
4586 | |
4587 | |
4588 | QualType AtomTy = pointerType->getPointeeType(); |
4589 | QualType ValType = AtomTy; |
4590 | if (IsC11) { |
4591 | if (!AtomTy->isAtomicType()) { |
4592 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_atomic) |
4593 | << Ptr->getType() << Ptr->getSourceRange(); |
4594 | return ExprError(); |
4595 | } |
4596 | if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) || |
4597 | AtomTy.getAddressSpace() == LangAS::opencl_constant) { |
4598 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_non_const_atomic) |
4599 | << (AtomTy.isConstQualified() ? 0 : 1) << Ptr->getType() |
4600 | << Ptr->getSourceRange(); |
4601 | return ExprError(); |
4602 | } |
4603 | ValType = AtomTy->getAs<AtomicType>()->getValueType(); |
4604 | } else if (Form != Load && Form != LoadCopy) { |
4605 | if (ValType.isConstQualified()) { |
4606 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_non_const_pointer) |
4607 | << Ptr->getType() << Ptr->getSourceRange(); |
4608 | return ExprError(); |
4609 | } |
4610 | } |
4611 | |
4612 | |
4613 | if (Form == Arithmetic) { |
4614 | |
4615 | if (IsAddSub && !ValType->isIntegerType() |
4616 | && !ValType->isPointerType()) { |
4617 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_atomic_int_or_ptr) |
4618 | << IsC11 << Ptr->getType() << Ptr->getSourceRange(); |
4619 | return ExprError(); |
4620 | } |
4621 | if (IsMinMax) { |
4622 | const BuiltinType *BT = ValType->getAs<BuiltinType>(); |
4623 | if (!BT || (BT->getKind() != BuiltinType::Int && |
4624 | BT->getKind() != BuiltinType::UInt)) { |
4625 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_int32_or_ptr); |
4626 | return ExprError(); |
4627 | } |
4628 | } |
4629 | if (!IsAddSub && !IsMinMax && !ValType->isIntegerType()) { |
4630 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_bitwise_needs_atomic_int) |
4631 | << IsC11 << Ptr->getType() << Ptr->getSourceRange(); |
4632 | return ExprError(); |
4633 | } |
4634 | if (IsC11 && ValType->isPointerType() && |
4635 | RequireCompleteType(Ptr->getBeginLoc(), ValType->getPointeeType(), |
4636 | diag::err_incomplete_type)) { |
4637 | return ExprError(); |
4638 | } |
4639 | } else if (IsN && !ValType->isIntegerType() && !ValType->isPointerType()) { |
4640 | |
4641 | |
4642 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_atomic_int_or_ptr) |
4643 | << IsC11 << Ptr->getType() << Ptr->getSourceRange(); |
4644 | return ExprError(); |
4645 | } |
4646 | |
4647 | if (!IsC11 && !AtomTy.isTriviallyCopyableType(Context) && |
4648 | !AtomTy->isScalarType()) { |
4649 | |
4650 | |
4651 | Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_trivial_copy) |
4652 | << Ptr->getType() << Ptr->getSourceRange(); |
4653 | return ExprError(); |
4654 | } |
4655 | |
4656 | switch (ValType.getObjCLifetime()) { |
4657 | case Qualifiers::OCL_None: |
4658 | case Qualifiers::OCL_ExplicitNone: |
4659 | |
4660 | break; |
4661 | |
4662 | case Qualifiers::OCL_Weak: |
4663 | case Qualifiers::OCL_Strong: |
4664 | case Qualifiers::OCL_Autoreleasing: |
4665 | |
4666 | |
4667 | Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership) |
4668 | << ValType << Ptr->getSourceRange(); |
4669 | return ExprError(); |
4670 | } |
4671 | |
4672 | |
4673 | |
4674 | |
4675 | |
4676 | ValType.removeLocalVolatile(); |
4677 | ValType.removeLocalConst(); |
4678 | QualType ResultType = ValType; |
4679 | if (Form == Copy || Form == LoadCopy || Form == GNUXchg || |
4680 | Form == Init) |
4681 | ResultType = Context.VoidTy; |
4682 | else if (Form == C11CmpXchg || Form == GNUCmpXchg) |
4683 | ResultType = Context.BoolTy; |
4684 | |
4685 | |
4686 | |
4687 | QualType ByValType = ValType; |
4688 | bool IsPassedByAddress = false; |
4689 | if (!IsC11 && !IsN) { |
4690 | ByValType = Ptr->getType(); |
4691 | IsPassedByAddress = true; |
4692 | } |
4693 | |
4694 | |
4695 | |
4696 | |
4697 | |
4698 | |
4699 | for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) { |
4700 | QualType Ty; |
4701 | if (i < NumVals[Form] + 1) { |
4702 | switch (i) { |
4703 | case 0: |
4704 | |
4705 | |
4706 | CheckNonNullArgument(*this, TheCall->getArg(i), DRE->getBeginLoc()); |
4707 | |
4708 | continue; |
4709 | case 1: |
4710 | |
4711 | |
4712 | |
4713 | |
4714 | assert(Form != Load); |
4715 | if (Form == Init || (Form == Arithmetic && ValType->isIntegerType())) |
4716 | Ty = ValType; |
4717 | else if (Form == Copy || Form == Xchg) { |
4718 | if (IsPassedByAddress) |
4719 | |
4720 | CheckNonNullArgument(*this, TheCall->getArg(i), DRE->getBeginLoc()); |
4721 | Ty = ByValType; |
4722 | } else if (Form == Arithmetic) |
4723 | Ty = Context.getPointerDiffType(); |
4724 | else { |
4725 | Expr *ValArg = TheCall->getArg(i); |
4726 | |
4727 | CheckNonNullArgument(*this, ValArg, DRE->getBeginLoc()); |
4728 | LangAS AS = LangAS::Default; |
4729 | |
4730 | if (const PointerType *PtrTy = |
4731 | ValArg->getType()->getAs<PointerType>()) { |
4732 | AS = PtrTy->getPointeeType().getAddressSpace(); |
4733 | } |
4734 | Ty = Context.getPointerType( |
4735 | Context.getAddrSpaceQualType(ValType.getUnqualifiedType(), AS)); |
4736 | } |
4737 | break; |
4738 | case 2: |
4739 | |
4740 | |
4741 | if (IsPassedByAddress) |
4742 | CheckNonNullArgument(*this, TheCall->getArg(i), DRE->getBeginLoc()); |
4743 | Ty = ByValType; |
4744 | break; |
4745 | case 3: |
4746 | |
4747 | Ty = Context.BoolTy; |
4748 | break; |
4749 | } |
4750 | } else { |
4751 | |
4752 | Ty = Context.IntTy; |
4753 | } |
4754 | |
4755 | InitializedEntity Entity = |
4756 | InitializedEntity::InitializeParameter(Context, Ty, false); |
4757 | ExprResult Arg = TheCall->getArg(i); |
4758 | Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); |
4759 | if (Arg.isInvalid()) |
4760 | return true; |
4761 | TheCall->setArg(i, Arg.get()); |
4762 | } |
4763 | |
4764 | |
4765 | SmallVector<Expr*, 5> SubExprs; |
4766 | SubExprs.push_back(Ptr); |
4767 | switch (Form) { |
4768 | case Init: |
4769 | |
4770 | SubExprs.push_back(TheCall->getArg(1)); |
4771 | break; |
4772 | case Load: |
4773 | SubExprs.push_back(TheCall->getArg(1)); |
4774 | break; |
4775 | case LoadCopy: |
4776 | case Copy: |
4777 | case Arithmetic: |
4778 | case Xchg: |
4779 | SubExprs.push_back(TheCall->getArg(2)); |
4780 | SubExprs.push_back(TheCall->getArg(1)); |
4781 | break; |
4782 | case GNUXchg: |
4783 | |
4784 | SubExprs.push_back(TheCall->getArg(3)); |
4785 | SubExprs.push_back(TheCall->getArg(1)); |
4786 | SubExprs.push_back(TheCall->getArg(2)); |
4787 | break; |
4788 | case C11CmpXchg: |
4789 | SubExprs.push_back(TheCall->getArg(3)); |
4790 | SubExprs.push_back(TheCall->getArg(1)); |
4791 | SubExprs.push_back(TheCall->getArg(4)); |
4792 | SubExprs.push_back(TheCall->getArg(2)); |
4793 | break; |
4794 | case GNUCmpXchg: |
4795 | SubExprs.push_back(TheCall->getArg(4)); |
4796 | SubExprs.push_back(TheCall->getArg(1)); |
4797 | SubExprs.push_back(TheCall->getArg(5)); |
4798 | SubExprs.push_back(TheCall->getArg(2)); |
4799 | SubExprs.push_back(TheCall->getArg(3)); |
4800 | break; |
4801 | } |
4802 | |
4803 | if (SubExprs.size() >= 2 && Form != Init) { |
4804 | llvm::APSInt Result(32); |
4805 | if (SubExprs[1]->isIntegerConstantExpr(Result, Context) && |
4806 | !isValidOrderingForOp(Result.getSExtValue(), Op)) |
4807 | Diag(SubExprs[1]->getBeginLoc(), |
4808 | diag::warn_atomic_op_has_invalid_memory_order) |
4809 | << SubExprs[1]->getSourceRange(); |
4810 | } |
4811 | |
4812 | if (auto ScopeModel = AtomicExpr::getScopeModel(Op)) { |
4813 | auto *Scope = TheCall->getArg(TheCall->getNumArgs() - 1); |
4814 | llvm::APSInt Result(32); |
4815 | if (Scope->isIntegerConstantExpr(Result, Context) && |
4816 | !ScopeModel->isValid(Result.getZExtValue())) { |
4817 | Diag(Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope) |
4818 | << Scope->getSourceRange(); |
4819 | } |
4820 | SubExprs.push_back(Scope); |
4821 | } |
4822 | |
4823 | AtomicExpr *AE = |
4824 | new (Context) AtomicExpr(TheCall->getCallee()->getBeginLoc(), SubExprs, |
4825 | ResultType, Op, TheCall->getRParenLoc()); |
4826 | |
4827 | if ((Op == AtomicExpr::AO__c11_atomic_load || |
4828 | Op == AtomicExpr::AO__c11_atomic_store || |
4829 | Op == AtomicExpr::AO__opencl_atomic_load || |
4830 | Op == AtomicExpr::AO__opencl_atomic_store ) && |
4831 | Context.AtomicUsesUnsupportedLibcall(AE)) |
4832 | Diag(AE->getBeginLoc(), diag::err_atomic_load_store_uses_lib) |
4833 | << ((Op == AtomicExpr::AO__c11_atomic_load || |
4834 | Op == AtomicExpr::AO__opencl_atomic_load) |
4835 | ? 0 |
4836 | : 1); |
4837 | |
4838 | return AE; |
4839 | } |
4840 | |
4841 | |
4842 | |
4843 | |
4844 | |
4845 | |
4846 | |
4847 | |
4848 | static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex) { |
4849 | FunctionDecl *Fn = E->getDirectCallee(); |
4850 | (0) . __assert_fail ("Fn && \"builtin call without direct callee!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 4850, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Fn && "builtin call without direct callee!"); |
4851 | |
4852 | ParmVarDecl *Param = Fn->getParamDecl(ArgIndex); |
4853 | InitializedEntity Entity = |
4854 | InitializedEntity::InitializeParameter(S.Context, Param); |
4855 | |
4856 | ExprResult Arg = E->getArg(0); |
4857 | Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg); |
4858 | if (Arg.isInvalid()) |
4859 | return true; |
4860 | |
4861 | E->setArg(ArgIndex, Arg.get()); |
4862 | return false; |
4863 | } |
4864 | |
4865 | |
4866 | |
4867 | |
4868 | |
4869 | |
4870 | |
4871 | |
4872 | ExprResult |
4873 | Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { |
4874 | CallExpr *TheCall = static_cast<CallExpr *>(TheCallResult.get()); |
4875 | Expr *Callee = TheCall->getCallee(); |
4876 | DeclRefExpr *DRE = cast<DeclRefExpr>(Callee->IgnoreParenCasts()); |
4877 | FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl()); |
4878 | |
4879 | |
4880 | if (TheCall->getNumArgs() < 1) { |
4881 | Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) |
4882 | << 0 << 1 << TheCall->getNumArgs() << Callee->getSourceRange(); |
4883 | return ExprError(); |
4884 | } |
4885 | |
4886 | |
4887 | |
4888 | |
4889 | |
4890 | |
4891 | Expr *FirstArg = TheCall->getArg(0); |
4892 | ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg); |
4893 | if (FirstArgResult.isInvalid()) |
4894 | return ExprError(); |
4895 | FirstArg = FirstArgResult.get(); |
4896 | TheCall->setArg(0, FirstArg); |
4897 | |
4898 | const PointerType *pointerType = FirstArg->getType()->getAs<PointerType>(); |
4899 | if (!pointerType) { |
4900 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) |
4901 | << FirstArg->getType() << FirstArg->getSourceRange(); |
4902 | return ExprError(); |
4903 | } |
4904 | |
4905 | QualType ValType = pointerType->getPointeeType(); |
4906 | if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && |
4907 | !ValType->isBlockPointerType()) { |
4908 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr) |
4909 | << FirstArg->getType() << FirstArg->getSourceRange(); |
4910 | return ExprError(); |
4911 | } |
4912 | |
4913 | if (ValType.isConstQualified()) { |
4914 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_cannot_be_const) |
4915 | << FirstArg->getType() << FirstArg->getSourceRange(); |
4916 | return ExprError(); |
4917 | } |
4918 | |
4919 | switch (ValType.getObjCLifetime()) { |
4920 | case Qualifiers::OCL_None: |
4921 | case Qualifiers::OCL_ExplicitNone: |
4922 | |
4923 | break; |
4924 | |
4925 | case Qualifiers::OCL_Weak: |
4926 | case Qualifiers::OCL_Strong: |
4927 | case Qualifiers::OCL_Autoreleasing: |
4928 | Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership) |
4929 | << ValType << FirstArg->getSourceRange(); |
4930 | return ExprError(); |
4931 | } |
4932 | |
4933 | |
4934 | ValType = ValType.getUnqualifiedType(); |
4935 | |
4936 | |
4937 | |
4938 | QualType ResultType = ValType; |
4939 | |
4940 | |
4941 | |
4942 | |
4943 | #define BUILTIN_ROW(x) \ |
4944 | { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \ |
4945 | Builtin::BI##x##_8, Builtin::BI##x##_16 } |
4946 | |
4947 | static const unsigned BuiltinIndices[][5] = { |
4948 | BUILTIN_ROW(__sync_fetch_and_add), |
4949 | BUILTIN_ROW(__sync_fetch_and_sub), |
4950 | BUILTIN_ROW(__sync_fetch_and_or), |
4951 | BUILTIN_ROW(__sync_fetch_and_and), |
4952 | BUILTIN_ROW(__sync_fetch_and_xor), |
4953 | BUILTIN_ROW(__sync_fetch_and_nand), |
4954 | |
4955 | BUILTIN_ROW(__sync_add_and_fetch), |
4956 | BUILTIN_ROW(__sync_sub_and_fetch), |
4957 | BUILTIN_ROW(__sync_and_and_fetch), |
4958 | BUILTIN_ROW(__sync_or_and_fetch), |
4959 | BUILTIN_ROW(__sync_xor_and_fetch), |
4960 | BUILTIN_ROW(__sync_nand_and_fetch), |
4961 | |
4962 | BUILTIN_ROW(__sync_val_compare_and_swap), |
4963 | BUILTIN_ROW(__sync_bool_compare_and_swap), |
4964 | BUILTIN_ROW(__sync_lock_test_and_set), |
4965 | BUILTIN_ROW(__sync_lock_release), |
4966 | BUILTIN_ROW(__sync_swap) |
4967 | }; |
4968 | #undef BUILTIN_ROW |
4969 | |
4970 | |
4971 | unsigned SizeIndex; |
4972 | switch (Context.getTypeSizeInChars(ValType).getQuantity()) { |
4973 | case 1: SizeIndex = 0; break; |
4974 | case 2: SizeIndex = 1; break; |
4975 | case 4: SizeIndex = 2; break; |
4976 | case 8: SizeIndex = 3; break; |
4977 | case 16: SizeIndex = 4; break; |
4978 | default: |
4979 | Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_pointer_size) |
4980 | << FirstArg->getType() << FirstArg->getSourceRange(); |
4981 | return ExprError(); |
4982 | } |
4983 | |
4984 | |
4985 | |
4986 | |
4987 | |
4988 | unsigned BuiltinID = FDecl->getBuiltinID(); |
4989 | unsigned BuiltinIndex, NumFixed = 1; |
4990 | bool WarnAboutSemanticsChange = false; |
4991 | switch (BuiltinID) { |
4992 | default: llvm_unreachable("Unknown overloaded atomic builtin!"); |
4993 | case Builtin::BI__sync_fetch_and_add: |
4994 | case Builtin::BI__sync_fetch_and_add_1: |
4995 | case Builtin::BI__sync_fetch_and_add_2: |
4996 | case Builtin::BI__sync_fetch_and_add_4: |
4997 | case Builtin::BI__sync_fetch_and_add_8: |
4998 | case Builtin::BI__sync_fetch_and_add_16: |
4999 | BuiltinIndex = 0; |
5000 | break; |
5001 | |
5002 | case Builtin::BI__sync_fetch_and_sub: |
5003 | case Builtin::BI__sync_fetch_and_sub_1: |
5004 | case Builtin::BI__sync_fetch_and_sub_2: |
5005 | case Builtin::BI__sync_fetch_and_sub_4: |
5006 | case Builtin::BI__sync_fetch_and_sub_8: |
5007 | case Builtin::BI__sync_fetch_and_sub_16: |
5008 | BuiltinIndex = 1; |
5009 | break; |
5010 | |
5011 | case Builtin::BI__sync_fetch_and_or: |
5012 | case Builtin::BI__sync_fetch_and_or_1: |
5013 | case Builtin::BI__sync_fetch_and_or_2: |
5014 | case Builtin::BI__sync_fetch_and_or_4: |
5015 | case Builtin::BI__sync_fetch_and_or_8: |
5016 | case Builtin::BI__sync_fetch_and_or_16: |
5017 | BuiltinIndex = 2; |
5018 | break; |
5019 | |
5020 | case Builtin::BI__sync_fetch_and_and: |
5021 | case Builtin::BI__sync_fetch_and_and_1: |
5022 | case Builtin::BI__sync_fetch_and_and_2: |
5023 | case Builtin::BI__sync_fetch_and_and_4: |
5024 | case Builtin::BI__sync_fetch_and_and_8: |
5025 | case Builtin::BI__sync_fetch_and_and_16: |
5026 | BuiltinIndex = 3; |
5027 | break; |
5028 | |
5029 | case Builtin::BI__sync_fetch_and_xor: |
5030 | case Builtin::BI__sync_fetch_and_xor_1: |
5031 | case Builtin::BI__sync_fetch_and_xor_2: |
5032 | case Builtin::BI__sync_fetch_and_xor_4: |
5033 | case Builtin::BI__sync_fetch_and_xor_8: |
5034 | case Builtin::BI__sync_fetch_and_xor_16: |
5035 | BuiltinIndex = 4; |
5036 | break; |
5037 | |
5038 | case Builtin::BI__sync_fetch_and_nand: |
5039 | case Builtin::BI__sync_fetch_and_nand_1: |
5040 | case Builtin::BI__sync_fetch_and_nand_2: |
5041 | case Builtin::BI__sync_fetch_and_nand_4: |
5042 | case Builtin::BI__sync_fetch_and_nand_8: |
5043 | case Builtin::BI__sync_fetch_and_nand_16: |
5044 | BuiltinIndex = 5; |
5045 | WarnAboutSemanticsChange = true; |
5046 | break; |
5047 | |
5048 | case Builtin::BI__sync_add_and_fetch: |
5049 | case Builtin::BI__sync_add_and_fetch_1: |
5050 | case Builtin::BI__sync_add_and_fetch_2: |
5051 | case Builtin::BI__sync_add_and_fetch_4: |
5052 | case Builtin::BI__sync_add_and_fetch_8: |
5053 | case Builtin::BI__sync_add_and_fetch_16: |
5054 | BuiltinIndex = 6; |
5055 | break; |
5056 | |
5057 | case Builtin::BI__sync_sub_and_fetch: |
5058 | case Builtin::BI__sync_sub_and_fetch_1: |
5059 | case Builtin::BI__sync_sub_and_fetch_2: |
5060 | case Builtin::BI__sync_sub_and_fetch_4: |
5061 | case Builtin::BI__sync_sub_and_fetch_8: |
5062 | case Builtin::BI__sync_sub_and_fetch_16: |
5063 | BuiltinIndex = 7; |
5064 | break; |
5065 | |
5066 | case Builtin::BI__sync_and_and_fetch: |
5067 | case Builtin::BI__sync_and_and_fetch_1: |
5068 | case Builtin::BI__sync_and_and_fetch_2: |
5069 | case Builtin::BI__sync_and_and_fetch_4: |
5070 | case Builtin::BI__sync_and_and_fetch_8: |
5071 | case Builtin::BI__sync_and_and_fetch_16: |
5072 | BuiltinIndex = 8; |
5073 | break; |
5074 | |
5075 | case Builtin::BI__sync_or_and_fetch: |
5076 | case Builtin::BI__sync_or_and_fetch_1: |
5077 | case Builtin::BI__sync_or_and_fetch_2: |
5078 | case Builtin::BI__sync_or_and_fetch_4: |
5079 | case Builtin::BI__sync_or_and_fetch_8: |
5080 | case Builtin::BI__sync_or_and_fetch_16: |
5081 | BuiltinIndex = 9; |
5082 | break; |
5083 | |
5084 | case Builtin::BI__sync_xor_and_fetch: |
5085 | case Builtin::BI__sync_xor_and_fetch_1: |
5086 | case Builtin::BI__sync_xor_and_fetch_2: |
5087 | case Builtin::BI__sync_xor_and_fetch_4: |
5088 | case Builtin::BI__sync_xor_and_fetch_8: |
5089 | case Builtin::BI__sync_xor_and_fetch_16: |
5090 | BuiltinIndex = 10; |
5091 | break; |
5092 | |
5093 | case Builtin::BI__sync_nand_and_fetch: |
5094 | case Builtin::BI__sync_nand_and_fetch_1: |
5095 | case Builtin::BI__sync_nand_and_fetch_2: |
5096 | case Builtin::BI__sync_nand_and_fetch_4: |
5097 | case Builtin::BI__sync_nand_and_fetch_8: |
5098 | case Builtin::BI__sync_nand_and_fetch_16: |
5099 | BuiltinIndex = 11; |
5100 | WarnAboutSemanticsChange = true; |
5101 | break; |
5102 | |
5103 | case Builtin::BI__sync_val_compare_and_swap: |
5104 | case Builtin::BI__sync_val_compare_and_swap_1: |
5105 | case Builtin::BI__sync_val_compare_and_swap_2: |
5106 | case Builtin::BI__sync_val_compare_and_swap_4: |
5107 | case Builtin::BI__sync_val_compare_and_swap_8: |
5108 | case Builtin::BI__sync_val_compare_and_swap_16: |
5109 | BuiltinIndex = 12; |
5110 | NumFixed = 2; |
5111 | break; |
5112 | |
5113 | case Builtin::BI__sync_bool_compare_and_swap: |
5114 | case Builtin::BI__sync_bool_compare_and_swap_1: |
5115 | case Builtin::BI__sync_bool_compare_and_swap_2: |
5116 | case Builtin::BI__sync_bool_compare_and_swap_4: |
5117 | case Builtin::BI__sync_bool_compare_and_swap_8: |
5118 | case Builtin::BI__sync_bool_compare_and_swap_16: |
5119 | BuiltinIndex = 13; |
5120 | NumFixed = 2; |
5121 | ResultType = Context.BoolTy; |
5122 | break; |
5123 | |
5124 | case Builtin::BI__sync_lock_test_and_set: |
5125 | case Builtin::BI__sync_lock_test_and_set_1: |
5126 | case Builtin::BI__sync_lock_test_and_set_2: |
5127 | case Builtin::BI__sync_lock_test_and_set_4: |
5128 | case Builtin::BI__sync_lock_test_and_set_8: |
5129 | case Builtin::BI__sync_lock_test_and_set_16: |
5130 | BuiltinIndex = 14; |
5131 | break; |
5132 | |
5133 | case Builtin::BI__sync_lock_release: |
5134 | case Builtin::BI__sync_lock_release_1: |
5135 | case Builtin::BI__sync_lock_release_2: |
5136 | case Builtin::BI__sync_lock_release_4: |
5137 | case Builtin::BI__sync_lock_release_8: |
5138 | case Builtin::BI__sync_lock_release_16: |
5139 | BuiltinIndex = 15; |
5140 | NumFixed = 0; |
5141 | ResultType = Context.VoidTy; |
5142 | break; |
5143 | |
5144 | case Builtin::BI__sync_swap: |
5145 | case Builtin::BI__sync_swap_1: |
5146 | case Builtin::BI__sync_swap_2: |
5147 | case Builtin::BI__sync_swap_4: |
5148 | case Builtin::BI__sync_swap_8: |
5149 | case Builtin::BI__sync_swap_16: |
5150 | BuiltinIndex = 16; |
5151 | break; |
5152 | } |
5153 | |
5154 | |
5155 | |
5156 | if (TheCall->getNumArgs() < 1+NumFixed) { |
5157 | Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) |
5158 | << 0 << 1 + NumFixed << TheCall->getNumArgs() |
5159 | << Callee->getSourceRange(); |
5160 | return ExprError(); |
5161 | } |
5162 | |
5163 | Diag(TheCall->getEndLoc(), diag::warn_atomic_implicit_seq_cst) |
5164 | << Callee->getSourceRange(); |
5165 | |
5166 | if (WarnAboutSemanticsChange) { |
5167 | Diag(TheCall->getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change) |
5168 | << Callee->getSourceRange(); |
5169 | } |
5170 | |
5171 | |
5172 | |
5173 | unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; |
5174 | const char *NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID); |
5175 | FunctionDecl *NewBuiltinDecl; |
5176 | if (NewBuiltinID == BuiltinID) |
5177 | NewBuiltinDecl = FDecl; |
5178 | else { |
5179 | |
5180 | DeclarationName DN(&Context.Idents.get(NewBuiltinName)); |
5181 | LookupResult Res(*this, DN, DRE->getBeginLoc(), LookupOrdinaryName); |
5182 | LookupName(Res, TUScope, ); |
5183 | assert(Res.getFoundDecl()); |
5184 | NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl()); |
5185 | if (!NewBuiltinDecl) |
5186 | return ExprError(); |
5187 | } |
5188 | |
5189 | |
5190 | |
5191 | |
5192 | for (unsigned i = 0; i != NumFixed; ++i) { |
5193 | ExprResult Arg = TheCall->getArg(i+1); |
5194 | |
5195 | |
5196 | |
5197 | |
5198 | InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, |
5199 | ValType, false); |
5200 | Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); |
5201 | if (Arg.isInvalid()) |
5202 | return ExprError(); |
5203 | |
5204 | |
5205 | |
5206 | |
5207 | |
5208 | |
5209 | |
5210 | TheCall->setArg(i+1, Arg.get()); |
5211 | } |
5212 | |
5213 | |
5214 | DeclRefExpr* NewDRE = DeclRefExpr::Create( |
5215 | Context, |
5216 | DRE->getQualifierLoc(), |
5217 | SourceLocation(), |
5218 | NewBuiltinDecl, |
5219 | false, |
5220 | DRE->getLocation(), |
5221 | Context.BuiltinFnTy, |
5222 | DRE->getValueKind()); |
5223 | |
5224 | |
5225 | |
5226 | QualType CalleePtrTy = Context.getPointerType(NewBuiltinDecl->getType()); |
5227 | ExprResult PromotedCall = ImpCastExprToType(NewDRE, CalleePtrTy, |
5228 | CK_BuiltinFnToFnPtr); |
5229 | TheCall->setCallee(PromotedCall.get()); |
5230 | |
5231 | |
5232 | |
5233 | |
5234 | TheCall->setType(ResultType); |
5235 | |
5236 | return TheCallResult; |
5237 | } |
5238 | |
5239 | |
5240 | |
5241 | |
5242 | |
5243 | |
5244 | |
5245 | ExprResult Sema::SemaBuiltinNontemporalOverloaded(ExprResult TheCallResult) { |
5246 | CallExpr *TheCall = (CallExpr *)TheCallResult.get(); |
5247 | DeclRefExpr *DRE = |
5248 | cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); |
5249 | FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl()); |
5250 | unsigned BuiltinID = FDecl->getBuiltinID(); |
5251 | (0) . __assert_fail ("(BuiltinID == Builtin..BI__builtin_nontemporal_store || BuiltinID == Builtin..BI__builtin_nontemporal_load) && \"Unexpected nontemporal load/store builtin!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5253, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((BuiltinID == Builtin::BI__builtin_nontemporal_store || |
5252 | (0) . __assert_fail ("(BuiltinID == Builtin..BI__builtin_nontemporal_store || BuiltinID == Builtin..BI__builtin_nontemporal_load) && \"Unexpected nontemporal load/store builtin!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5253, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> BuiltinID == Builtin::BI__builtin_nontemporal_load) && |
5253 | (0) . __assert_fail ("(BuiltinID == Builtin..BI__builtin_nontemporal_store || BuiltinID == Builtin..BI__builtin_nontemporal_load) && \"Unexpected nontemporal load/store builtin!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5253, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Unexpected nontemporal load/store builtin!"); |
5254 | bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store; |
5255 | unsigned numArgs = isStore ? 2 : 1; |
5256 | |
5257 | |
5258 | if (checkArgCount(*this, TheCall, numArgs)) |
5259 | return ExprError(); |
5260 | |
5261 | |
5262 | |
5263 | |
5264 | |
5265 | Expr *PointerArg = TheCall->getArg(numArgs - 1); |
5266 | ExprResult PointerArgResult = |
5267 | DefaultFunctionArrayLvalueConversion(PointerArg); |
5268 | |
5269 | if (PointerArgResult.isInvalid()) |
5270 | return ExprError(); |
5271 | PointerArg = PointerArgResult.get(); |
5272 | TheCall->setArg(numArgs - 1, PointerArg); |
5273 | |
5274 | const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>(); |
5275 | if (!pointerType) { |
5276 | Diag(DRE->getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer) |
5277 | << PointerArg->getType() << PointerArg->getSourceRange(); |
5278 | return ExprError(); |
5279 | } |
5280 | |
5281 | QualType ValType = pointerType->getPointeeType(); |
5282 | |
5283 | |
5284 | ValType = ValType.getUnqualifiedType(); |
5285 | if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && |
5286 | !ValType->isBlockPointerType() && !ValType->isFloatingType() && |
5287 | !ValType->isVectorType()) { |
5288 | Diag(DRE->getBeginLoc(), |
5289 | diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector) |
5290 | << PointerArg->getType() << PointerArg->getSourceRange(); |
5291 | return ExprError(); |
5292 | } |
5293 | |
5294 | if (!isStore) { |
5295 | TheCall->setType(ValType); |
5296 | return TheCallResult; |
5297 | } |
5298 | |
5299 | ExprResult ValArg = TheCall->getArg(0); |
5300 | InitializedEntity Entity = InitializedEntity::InitializeParameter( |
5301 | Context, ValType, false); |
5302 | ValArg = PerformCopyInitialization(Entity, SourceLocation(), ValArg); |
5303 | if (ValArg.isInvalid()) |
5304 | return ExprError(); |
5305 | |
5306 | TheCall->setArg(0, ValArg.get()); |
5307 | TheCall->setType(Context.VoidTy); |
5308 | return TheCallResult; |
5309 | } |
5310 | |
5311 | |
5312 | |
5313 | |
5314 | |
5315 | bool Sema::CheckObjCString(Expr *Arg) { |
5316 | Arg = Arg->IgnoreParenCasts(); |
5317 | StringLiteral *Literal = dyn_cast<StringLiteral>(Arg); |
5318 | |
5319 | if (!Literal || !Literal->isAscii()) { |
5320 | Diag(Arg->getBeginLoc(), diag::err_cfstring_literal_not_string_constant) |
5321 | << Arg->getSourceRange(); |
5322 | return true; |
5323 | } |
5324 | |
5325 | if (Literal->containsNonAsciiOrNull()) { |
5326 | StringRef String = Literal->getString(); |
5327 | unsigned NumBytes = String.size(); |
5328 | SmallVector<llvm::UTF16, 128> ToBuf(NumBytes); |
5329 | const llvm::UTF8 *FromPtr = (const llvm::UTF8 *)String.data(); |
5330 | llvm::UTF16 *ToPtr = &ToBuf[0]; |
5331 | |
5332 | llvm::ConversionResult Result = |
5333 | llvm::ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, &ToPtr, |
5334 | ToPtr + NumBytes, llvm::strictConversion); |
5335 | |
5336 | if (Result != llvm::conversionOK) |
5337 | Diag(Arg->getBeginLoc(), diag::warn_cfstring_truncated) |
5338 | << Arg->getSourceRange(); |
5339 | } |
5340 | return false; |
5341 | } |
5342 | |
5343 | |
5344 | |
5345 | ExprResult Sema::CheckOSLogFormatStringArg(Expr *Arg) { |
5346 | Arg = Arg->IgnoreParenCasts(); |
5347 | auto *Literal = dyn_cast<StringLiteral>(Arg); |
5348 | if (!Literal) { |
5349 | if (auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) { |
5350 | Literal = ObjcLiteral->getString(); |
5351 | } |
5352 | } |
5353 | |
5354 | if (!Literal || (!Literal->isAscii() && !Literal->isUTF8())) { |
5355 | return ExprError( |
5356 | Diag(Arg->getBeginLoc(), diag::err_os_log_format_not_string_constant) |
5357 | << Arg->getSourceRange()); |
5358 | } |
5359 | |
5360 | ExprResult Result(Literal); |
5361 | QualType ResultTy = Context.getPointerType(Context.CharTy.withConst()); |
5362 | InitializedEntity Entity = |
5363 | InitializedEntity::InitializeParameter(Context, ResultTy, false); |
5364 | Result = PerformCopyInitialization(Entity, SourceLocation(), Result); |
5365 | return Result; |
5366 | } |
5367 | |
5368 | |
5369 | |
5370 | static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) { |
5371 | const llvm::Triple &TT = S.Context.getTargetInfo().getTriple(); |
5372 | bool IsX64 = TT.getArch() == llvm::Triple::x86_64; |
5373 | bool IsAArch64 = TT.getArch() == llvm::Triple::aarch64; |
5374 | bool IsWindows = TT.isOSWindows(); |
5375 | bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start; |
5376 | if (IsX64 || IsAArch64) { |
5377 | CallingConv CC = CC_C; |
5378 | if (const FunctionDecl *FD = S.getCurFunctionDecl()) |
5379 | CC = FD->getType()->getAs<FunctionType>()->getCallConv(); |
5380 | if (IsMSVAStart) { |
5381 | |
5382 | if (CC == CC_X86_64SysV || (!IsWindows && CC != CC_Win64)) |
5383 | return S.Diag(Fn->getBeginLoc(), |
5384 | diag::err_ms_va_start_used_in_sysv_function); |
5385 | } else { |
5386 | |
5387 | |
5388 | |
5389 | |
5390 | if ((IsWindows && CC == CC_X86_64SysV) || |
5391 | (!IsWindows && CC == CC_Win64)) |
5392 | return S.Diag(Fn->getBeginLoc(), |
5393 | diag::err_va_start_used_in_wrong_abi_function) |
5394 | << !IsWindows; |
5395 | } |
5396 | return false; |
5397 | } |
5398 | |
5399 | if (IsMSVAStart) |
5400 | return S.Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only); |
5401 | return false; |
5402 | } |
5403 | |
5404 | static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, |
5405 | ParmVarDecl **LastParam = nullptr) { |
5406 | |
5407 | |
5408 | bool IsVariadic = false; |
5409 | ArrayRef<ParmVarDecl *> Params; |
5410 | DeclContext *Caller = S.CurContext; |
5411 | if (auto *Block = dyn_cast<BlockDecl>(Caller)) { |
5412 | IsVariadic = Block->isVariadic(); |
5413 | Params = Block->parameters(); |
5414 | } else if (auto *FD = dyn_cast<FunctionDecl>(Caller)) { |
5415 | IsVariadic = FD->isVariadic(); |
5416 | Params = FD->parameters(); |
5417 | } else if (auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) { |
5418 | IsVariadic = MD->isVariadic(); |
5419 | |
5420 | Params = MD->parameters(); |
5421 | } else if (isa<CapturedDecl>(Caller)) { |
5422 | |
5423 | S.Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt); |
5424 | return true; |
5425 | } else { |
5426 | |
5427 | S.Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function); |
5428 | return true; |
5429 | } |
5430 | |
5431 | if (!IsVariadic) { |
5432 | S.Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function); |
5433 | return true; |
5434 | } |
5435 | |
5436 | if (LastParam) |
5437 | *LastParam = Params.empty() ? nullptr : Params.back(); |
5438 | |
5439 | return false; |
5440 | } |
5441 | |
5442 | |
5443 | |
5444 | |
5445 | bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) { |
5446 | Expr *Fn = TheCall->getCallee(); |
5447 | |
5448 | if (checkVAStartABI(*this, BuiltinID, Fn)) |
5449 | return true; |
5450 | |
5451 | if (TheCall->getNumArgs() > 2) { |
5452 | Diag(TheCall->getArg(2)->getBeginLoc(), |
5453 | diag::err_typecheck_call_too_many_args) |
5454 | << 0 << 2 << TheCall->getNumArgs() |
5455 | << Fn->getSourceRange() |
5456 | << SourceRange(TheCall->getArg(2)->getBeginLoc(), |
5457 | (*(TheCall->arg_end() - 1))->getEndLoc()); |
5458 | return true; |
5459 | } |
5460 | |
5461 | if (TheCall->getNumArgs() < 2) { |
5462 | return Diag(TheCall->getEndLoc(), |
5463 | diag::err_typecheck_call_too_few_args_at_least) |
5464 | << 0 << 2 << TheCall->getNumArgs(); |
5465 | } |
5466 | |
5467 | |
5468 | if (checkBuiltinArgument(*this, TheCall, 0)) |
5469 | return true; |
5470 | |
5471 | |
5472 | ParmVarDecl *LastParam; |
5473 | if (checkVAStartIsInVariadicFunction(*this, Fn, &LastParam)) |
5474 | return true; |
5475 | |
5476 | |
5477 | |
5478 | bool SecondArgIsLastNamedArgument = false; |
5479 | const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts(); |
5480 | |
5481 | |
5482 | |
5483 | QualType Type; |
5484 | SourceLocation ParamLoc; |
5485 | bool IsCRegister = false; |
5486 | |
5487 | if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) { |
5488 | if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) { |
5489 | SecondArgIsLastNamedArgument = PV == LastParam; |
5490 | |
5491 | Type = PV->getType(); |
5492 | ParamLoc = PV->getLocation(); |
5493 | IsCRegister = |
5494 | PV->getStorageClass() == SC_Register && !getLangOpts().CPlusPlus; |
5495 | } |
5496 | } |
5497 | |
5498 | if (!SecondArgIsLastNamedArgument) |
5499 | Diag(TheCall->getArg(1)->getBeginLoc(), |
5500 | diag::warn_second_arg_of_va_start_not_last_named_param); |
5501 | else if (IsCRegister || Type->isReferenceType() || |
5502 | Type->isSpecificBuiltinType(BuiltinType::Float) || [=] { |
5503 | |
5504 | |
5505 | if (!Type->isPromotableIntegerType()) |
5506 | return false; |
5507 | if (!Type->isEnumeralType()) |
5508 | return true; |
5509 | const EnumDecl *ED = Type->getAs<EnumType>()->getDecl(); |
5510 | return !(ED && |
5511 | Context.typesAreCompatible(ED->getPromotionType(), Type)); |
5512 | }()) { |
5513 | unsigned Reason = 0; |
5514 | if (Type->isReferenceType()) Reason = 1; |
5515 | else if (IsCRegister) Reason = 2; |
5516 | Diag(Arg->getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason; |
5517 | Diag(ParamLoc, diag::note_parameter_type) << Type; |
5518 | } |
5519 | |
5520 | TheCall->setType(Context.VoidTy); |
5521 | return false; |
5522 | } |
5523 | |
5524 | bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) { |
5525 | |
5526 | |
5527 | |
5528 | Expr *Func = Call->getCallee(); |
5529 | |
5530 | if (Call->getNumArgs() < 3) |
5531 | return Diag(Call->getEndLoc(), |
5532 | diag::err_typecheck_call_too_few_args_at_least) |
5533 | << 0 << 3 << Call->getNumArgs(); |
5534 | |
5535 | |
5536 | if (checkBuiltinArgument(*this, Call, 0)) |
5537 | return true; |
5538 | |
5539 | |
5540 | if (checkVAStartIsInVariadicFunction(*this, Func)) |
5541 | return true; |
5542 | |
5543 | |
5544 | |
5545 | const Expr *Arg1 = Call->getArg(1)->IgnoreParens(); |
5546 | const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr(); |
5547 | |
5548 | const Expr *Arg2 = Call->getArg(2)->IgnoreParens(); |
5549 | const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr(); |
5550 | |
5551 | const QualType &ConstCharPtrTy = |
5552 | Context.getPointerType(Context.CharTy.withConst()); |
5553 | if (!Arg1Ty->isPointerType() || |
5554 | Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy) |
5555 | Diag(Arg1->getBeginLoc(), diag::err_typecheck_convert_incompatible) |
5556 | << Arg1->getType() << ConstCharPtrTy << 1 |
5557 | << 0 |
5558 | << 3 |
5559 | << 2 << Arg1->getType() << ConstCharPtrTy; |
5560 | |
5561 | const QualType SizeTy = Context.getSizeType(); |
5562 | if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy) |
5563 | Diag(Arg2->getBeginLoc(), diag::err_typecheck_convert_incompatible) |
5564 | << Arg2->getType() << SizeTy << 1 |
5565 | << 0 |
5566 | << 3 |
5567 | << 3 << Arg2->getType() << SizeTy; |
5568 | |
5569 | return false; |
5570 | } |
5571 | |
5572 | |
5573 | |
5574 | bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { |
5575 | if (TheCall->getNumArgs() < 2) |
5576 | return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args) |
5577 | << 0 << 2 << TheCall->getNumArgs() ; |
5578 | if (TheCall->getNumArgs() > 2) |
5579 | return Diag(TheCall->getArg(2)->getBeginLoc(), |
5580 | diag::err_typecheck_call_too_many_args) |
5581 | << 0 << 2 << TheCall->getNumArgs() |
5582 | << SourceRange(TheCall->getArg(2)->getBeginLoc(), |
5583 | (*(TheCall->arg_end() - 1))->getEndLoc()); |
5584 | |
5585 | ExprResult OrigArg0 = TheCall->getArg(0); |
5586 | ExprResult OrigArg1 = TheCall->getArg(1); |
5587 | |
5588 | |
5589 | |
5590 | QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false); |
5591 | if (OrigArg0.isInvalid() || OrigArg1.isInvalid()) |
5592 | return true; |
5593 | |
5594 | |
5595 | |
5596 | |
5597 | TheCall->setArg(0, OrigArg0.get()); |
5598 | TheCall->setArg(1, OrigArg1.get()); |
5599 | |
5600 | if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent()) |
5601 | return false; |
5602 | |
5603 | |
5604 | |
5605 | if (Res.isNull() || !Res->isRealFloatingType()) |
5606 | return Diag(OrigArg0.get()->getBeginLoc(), |
5607 | diag::err_typecheck_call_invalid_ordered_compare) |
5608 | << OrigArg0.get()->getType() << OrigArg1.get()->getType() |
5609 | << SourceRange(OrigArg0.get()->getBeginLoc(), |
5610 | OrigArg1.get()->getEndLoc()); |
5611 | |
5612 | return false; |
5613 | } |
5614 | |
5615 | |
5616 | |
5617 | |
5618 | |
5619 | bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) { |
5620 | if (TheCall->getNumArgs() < NumArgs) |
5621 | return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args) |
5622 | << 0 << NumArgs << TheCall->getNumArgs() ; |
5623 | if (TheCall->getNumArgs() > NumArgs) |
5624 | return Diag(TheCall->getArg(NumArgs)->getBeginLoc(), |
5625 | diag::err_typecheck_call_too_many_args) |
5626 | << 0 << NumArgs << TheCall->getNumArgs() |
5627 | << SourceRange(TheCall->getArg(NumArgs)->getBeginLoc(), |
5628 | (*(TheCall->arg_end() - 1))->getEndLoc()); |
5629 | |
5630 | Expr *OrigArg = TheCall->getArg(NumArgs-1); |
5631 | |
5632 | if (OrigArg->isTypeDependent()) |
5633 | return false; |
5634 | |
5635 | |
5636 | if (!OrigArg->getType()->isRealFloatingType()) |
5637 | return Diag(OrigArg->getBeginLoc(), |
5638 | diag::err_typecheck_call_invalid_unary_fp) |
5639 | << OrigArg->getType() << OrigArg->getSourceRange(); |
5640 | |
5641 | |
5642 | |
5643 | if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) { |
5644 | |
5645 | if (Cast->getCastKind() == CK_FloatingCast) { |
5646 | Expr *CastArg = Cast->getSubExpr(); |
5647 | if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) { |
5648 | (0) . __assert_fail ("(Cast->getType()->isSpecificBuiltinType(BuiltinType..Double) || Cast->getType()->isSpecificBuiltinType(BuiltinType..Float) || Cast->getType()->isSpecificBuiltinType(BuiltinType..LongDouble)) && \"promotion from float to either float, double, or long double is \" \"the only expected cast here\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5653, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert( |
5649 | (0) . __assert_fail ("(Cast->getType()->isSpecificBuiltinType(BuiltinType..Double) || Cast->getType()->isSpecificBuiltinType(BuiltinType..Float) || Cast->getType()->isSpecificBuiltinType(BuiltinType..LongDouble)) && \"promotion from float to either float, double, or long double is \" \"the only expected cast here\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5653, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> (Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) || |
5650 | (0) . __assert_fail ("(Cast->getType()->isSpecificBuiltinType(BuiltinType..Double) || Cast->getType()->isSpecificBuiltinType(BuiltinType..Float) || Cast->getType()->isSpecificBuiltinType(BuiltinType..LongDouble)) && \"promotion from float to either float, double, or long double is \" \"the only expected cast here\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5653, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> Cast->getType()->isSpecificBuiltinType(BuiltinType::Float) || |
5651 | (0) . __assert_fail ("(Cast->getType()->isSpecificBuiltinType(BuiltinType..Double) || Cast->getType()->isSpecificBuiltinType(BuiltinType..Float) || Cast->getType()->isSpecificBuiltinType(BuiltinType..LongDouble)) && \"promotion from float to either float, double, or long double is \" \"the only expected cast here\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5653, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> Cast->getType()->isSpecificBuiltinType(BuiltinType::LongDouble)) && |
5652 | (0) . __assert_fail ("(Cast->getType()->isSpecificBuiltinType(BuiltinType..Double) || Cast->getType()->isSpecificBuiltinType(BuiltinType..Float) || Cast->getType()->isSpecificBuiltinType(BuiltinType..LongDouble)) && \"promotion from float to either float, double, or long double is \" \"the only expected cast here\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5653, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "promotion from float to either float, double, or long double is " |
5653 | (0) . __assert_fail ("(Cast->getType()->isSpecificBuiltinType(BuiltinType..Double) || Cast->getType()->isSpecificBuiltinType(BuiltinType..Float) || Cast->getType()->isSpecificBuiltinType(BuiltinType..LongDouble)) && \"promotion from float to either float, double, or long double is \" \"the only expected cast here\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 5653, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "the only expected cast here"); |
5654 | Cast->setSubExpr(nullptr); |
5655 | TheCall->setArg(NumArgs-1, CastArg); |
5656 | } |
5657 | } |
5658 | } |
5659 | |
5660 | return false; |
5661 | } |
5662 | |
5663 | |
5664 | |
5665 | |
5666 | |
5667 | |
5668 | |
5669 | |
5670 | bool Sema::SemaBuiltinVSX(CallExpr *TheCall) { |
5671 | unsigned ExpectedNumArgs = 3; |
5672 | if (TheCall->getNumArgs() < ExpectedNumArgs) |
5673 | return Diag(TheCall->getEndLoc(), |
5674 | diag::err_typecheck_call_too_few_args_at_least) |
5675 | << 0 << ExpectedNumArgs << TheCall->getNumArgs() |
5676 | << TheCall->getSourceRange(); |
5677 | |
5678 | if (TheCall->getNumArgs() > ExpectedNumArgs) |
5679 | return Diag(TheCall->getEndLoc(), |
5680 | diag::err_typecheck_call_too_many_args_at_most) |
5681 | << 0 << ExpectedNumArgs << TheCall->getNumArgs() |
5682 | << TheCall->getSourceRange(); |
5683 | |
5684 | |
5685 | llvm::APSInt Value; |
5686 | if(!TheCall->getArg(2)->isIntegerConstantExpr(Value, Context)) |
5687 | return Diag(TheCall->getBeginLoc(), |
5688 | diag::err_vsx_builtin_nonconstant_argument) |
5689 | << 3 << TheCall->getDirectCallee() |
5690 | << SourceRange(TheCall->getArg(2)->getBeginLoc(), |
5691 | TheCall->getArg(2)->getEndLoc()); |
5692 | |
5693 | QualType Arg1Ty = TheCall->getArg(0)->getType(); |
5694 | QualType Arg2Ty = TheCall->getArg(1)->getType(); |
5695 | |
5696 | |
5697 | SourceLocation BuiltinLoc = TheCall->getBeginLoc(); |
5698 | if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) || |
5699 | (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) { |
5700 | return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector) |
5701 | << TheCall->getDirectCallee() |
5702 | << SourceRange(TheCall->getArg(0)->getBeginLoc(), |
5703 | TheCall->getArg(1)->getEndLoc()); |
5704 | } |
5705 | |
5706 | |
5707 | if (!Context.hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) { |
5708 | return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector) |
5709 | << TheCall->getDirectCallee() |
5710 | << SourceRange(TheCall->getArg(0)->getBeginLoc(), |
5711 | TheCall->getArg(1)->getEndLoc()); |
5712 | } |
5713 | |
5714 | |
5715 | |
5716 | |
5717 | TheCall->setType(Arg1Ty); |
5718 | |
5719 | return false; |
5720 | } |
5721 | |
5722 | |
5723 | |
5724 | ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { |
5725 | if (TheCall->getNumArgs() < 2) |
5726 | return ExprError(Diag(TheCall->getEndLoc(), |
5727 | diag::err_typecheck_call_too_few_args_at_least) |
5728 | << 0 << 2 << TheCall->getNumArgs() |
5729 | << TheCall->getSourceRange()); |
5730 | |
5731 | |
5732 | |
5733 | |
5734 | QualType resType = TheCall->getArg(0)->getType(); |
5735 | unsigned numElements = 0; |
5736 | |
5737 | if (!TheCall->getArg(0)->isTypeDependent() && |
5738 | !TheCall->getArg(1)->isTypeDependent()) { |
5739 | QualType LHSType = TheCall->getArg(0)->getType(); |
5740 | QualType RHSType = TheCall->getArg(1)->getType(); |
5741 | |
5742 | if (!LHSType->isVectorType() || !RHSType->isVectorType()) |
5743 | return ExprError( |
5744 | Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_non_vector) |
5745 | << TheCall->getDirectCallee() |
5746 | << SourceRange(TheCall->getArg(0)->getBeginLoc(), |
5747 | TheCall->getArg(1)->getEndLoc())); |
5748 | |
5749 | numElements = LHSType->getAs<VectorType>()->getNumElements(); |
5750 | unsigned numResElements = TheCall->getNumArgs() - 2; |
5751 | |
5752 | |
5753 | |
5754 | |
5755 | if (TheCall->getNumArgs() == 2) { |
5756 | if (!RHSType->hasIntegerRepresentation() || |
5757 | RHSType->getAs<VectorType>()->getNumElements() != numElements) |
5758 | return ExprError(Diag(TheCall->getBeginLoc(), |
5759 | diag::err_vec_builtin_incompatible_vector) |
5760 | << TheCall->getDirectCallee() |
5761 | << SourceRange(TheCall->getArg(1)->getBeginLoc(), |
5762 | TheCall->getArg(1)->getEndLoc())); |
5763 | } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) { |
5764 | return ExprError(Diag(TheCall->getBeginLoc(), |
5765 | diag::err_vec_builtin_incompatible_vector) |
5766 | << TheCall->getDirectCallee() |
5767 | << SourceRange(TheCall->getArg(0)->getBeginLoc(), |
5768 | TheCall->getArg(1)->getEndLoc())); |
5769 | } else if (numElements != numResElements) { |
5770 | QualType eltType = LHSType->getAs<VectorType>()->getElementType(); |
5771 | resType = Context.getVectorType(eltType, numResElements, |
5772 | VectorType::GenericVector); |
5773 | } |
5774 | } |
5775 | |
5776 | for (unsigned i = 2; i < TheCall->getNumArgs(); i++) { |
5777 | if (TheCall->getArg(i)->isTypeDependent() || |
5778 | TheCall->getArg(i)->isValueDependent()) |
5779 | continue; |
5780 | |
5781 | llvm::APSInt Result(32); |
5782 | if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context)) |
5783 | return ExprError(Diag(TheCall->getBeginLoc(), |
5784 | diag::err_shufflevector_nonconstant_argument) |
5785 | << TheCall->getArg(i)->getSourceRange()); |
5786 | |
5787 | |
5788 | if (Result.isSigned() && Result.isAllOnesValue()) |
5789 | continue; |
5790 | |
5791 | if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2) |
5792 | return ExprError(Diag(TheCall->getBeginLoc(), |
5793 | diag::err_shufflevector_argument_too_large) |
5794 | << TheCall->getArg(i)->getSourceRange()); |
5795 | } |
5796 | |
5797 | SmallVector<Expr*, 32> exprs; |
5798 | |
5799 | for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) { |
5800 | exprs.push_back(TheCall->getArg(i)); |
5801 | TheCall->setArg(i, nullptr); |
5802 | } |
5803 | |
5804 | return new (Context) ShuffleVectorExpr(Context, exprs, resType, |
5805 | TheCall->getCallee()->getBeginLoc(), |
5806 | TheCall->getRParenLoc()); |
5807 | } |
5808 | |
5809 | |
5810 | ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, |
5811 | SourceLocation BuiltinLoc, |
5812 | SourceLocation RParenLoc) { |
5813 | ExprValueKind VK = VK_RValue; |
5814 | ExprObjectKind OK = OK_Ordinary; |
5815 | QualType DstTy = TInfo->getType(); |
5816 | QualType SrcTy = E->getType(); |
5817 | |
5818 | if (!SrcTy->isVectorType() && !SrcTy->isDependentType()) |
5819 | return ExprError(Diag(BuiltinLoc, |
5820 | diag::err_convertvector_non_vector) |
5821 | << E->getSourceRange()); |
5822 | if (!DstTy->isVectorType() && !DstTy->isDependentType()) |
5823 | return ExprError(Diag(BuiltinLoc, |
5824 | diag::err_convertvector_non_vector_type)); |
5825 | |
5826 | if (!SrcTy->isDependentType() && !DstTy->isDependentType()) { |
5827 | unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements(); |
5828 | unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements(); |
5829 | if (SrcElts != DstElts) |
5830 | return ExprError(Diag(BuiltinLoc, |
5831 | diag::err_convertvector_incompatible_vector) |
5832 | << E->getSourceRange()); |
5833 | } |
5834 | |
5835 | return new (Context) |
5836 | ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc); |
5837 | } |
5838 | |
5839 | |
5840 | |
5841 | |
5842 | bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { |
5843 | unsigned NumArgs = TheCall->getNumArgs(); |
5844 | |
5845 | if (NumArgs > 3) |
5846 | return Diag(TheCall->getEndLoc(), |
5847 | diag::err_typecheck_call_too_many_args_at_most) |
5848 | << 0 << 3 << NumArgs << TheCall->getSourceRange(); |
5849 | |
5850 | |
5851 | |
5852 | for (unsigned i = 1; i != NumArgs; ++i) |
5853 | if (SemaBuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3)) |
5854 | return true; |
5855 | |
5856 | return false; |
5857 | } |
5858 | |
5859 | |
5860 | |
5861 | |
5862 | bool Sema::SemaBuiltinAssume(CallExpr *TheCall) { |
5863 | Expr *Arg = TheCall->getArg(0); |
5864 | if (Arg->isInstantiationDependent()) return false; |
5865 | |
5866 | if (Arg->HasSideEffects(Context)) |
5867 | Diag(Arg->getBeginLoc(), diag::warn_assume_side_effects) |
5868 | << Arg->getSourceRange() |
5869 | << cast<FunctionDecl>(TheCall->getCalleeDecl())->getIdentifier(); |
5870 | |
5871 | return false; |
5872 | } |
5873 | |
5874 | |
5875 | |
5876 | |
5877 | bool Sema::SemaBuiltinAllocaWithAlign(CallExpr *TheCall) { |
5878 | |
5879 | Expr *Arg = TheCall->getArg(1); |
5880 | |
5881 | |
5882 | if (!Arg->isTypeDependent() && !Arg->isValueDependent()) { |
5883 | if (const auto *UE = |
5884 | dyn_cast<UnaryExprOrTypeTraitExpr>(Arg->IgnoreParenImpCasts())) |
5885 | if (UE->getKind() == UETT_AlignOf || |
5886 | UE->getKind() == UETT_PreferredAlignOf) |
5887 | Diag(TheCall->getBeginLoc(), diag::warn_alloca_align_alignof) |
5888 | << Arg->getSourceRange(); |
5889 | |
5890 | llvm::APSInt Result = Arg->EvaluateKnownConstInt(Context); |
5891 | |
5892 | if (!Result.isPowerOf2()) |
5893 | return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two) |
5894 | << Arg->getSourceRange(); |
5895 | |
5896 | if (Result < Context.getCharWidth()) |
5897 | return Diag(TheCall->getBeginLoc(), diag::err_alignment_too_small) |
5898 | << (unsigned)Context.getCharWidth() << Arg->getSourceRange(); |
5899 | |
5900 | if (Result > std::numeric_limits<int32_t>::max()) |
5901 | return Diag(TheCall->getBeginLoc(), diag::err_alignment_too_big) |
5902 | << std::numeric_limits<int32_t>::max() << Arg->getSourceRange(); |
5903 | } |
5904 | |
5905 | return false; |
5906 | } |
5907 | |
5908 | |
5909 | |
5910 | bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) { |
5911 | unsigned NumArgs = TheCall->getNumArgs(); |
5912 | |
5913 | if (NumArgs > 3) |
5914 | return Diag(TheCall->getEndLoc(), |
5915 | diag::err_typecheck_call_too_many_args_at_most) |
5916 | << 0 << 3 << NumArgs << TheCall->getSourceRange(); |
5917 | |
5918 | |
5919 | Expr *Arg = TheCall->getArg(1); |
5920 | |
5921 | |
5922 | if (!Arg->isTypeDependent() && !Arg->isValueDependent()) { |
5923 | llvm::APSInt Result; |
5924 | if (SemaBuiltinConstantArg(TheCall, 1, Result)) |
5925 | return true; |
5926 | |
5927 | if (!Result.isPowerOf2()) |
5928 | return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two) |
5929 | << Arg->getSourceRange(); |
5930 | } |
5931 | |
5932 | if (NumArgs > 2) { |
5933 | ExprResult Arg(TheCall->getArg(2)); |
5934 | InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, |
5935 | Context.getSizeType(), false); |
5936 | Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); |
5937 | if (Arg.isInvalid()) return true; |
5938 | TheCall->setArg(2, Arg.get()); |
5939 | } |
5940 | |
5941 | return false; |
5942 | } |
5943 | |
5944 | bool Sema::SemaBuiltinOSLogFormat(CallExpr *TheCall) { |
5945 | unsigned BuiltinID = |
5946 | cast<FunctionDecl>(TheCall->getCalleeDecl())->getBuiltinID(); |
5947 | bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size; |
5948 | |
5949 | unsigned NumArgs = TheCall->getNumArgs(); |
5950 | unsigned NumRequiredArgs = IsSizeCall ? 1 : 2; |
5951 | if (NumArgs < NumRequiredArgs) { |
5952 | return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args) |
5953 | << 0 << NumRequiredArgs << NumArgs |
5954 | << TheCall->getSourceRange(); |
5955 | } |
5956 | if (NumArgs >= NumRequiredArgs + 0x100) { |
5957 | return Diag(TheCall->getEndLoc(), |
5958 | diag::err_typecheck_call_too_many_args_at_most) |
5959 | << 0 << (NumRequiredArgs + 0xff) << NumArgs |
5960 | << TheCall->getSourceRange(); |
5961 | } |
5962 | unsigned i = 0; |
5963 | |
5964 | |
5965 | if (!IsSizeCall) { |
5966 | ExprResult Arg(TheCall->getArg(i)); |
5967 | InitializedEntity Entity = InitializedEntity::InitializeParameter( |
5968 | Context, Context.VoidPtrTy, false); |
5969 | Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); |
5970 | if (Arg.isInvalid()) |
5971 | return true; |
5972 | TheCall->setArg(i, Arg.get()); |
5973 | i++; |
5974 | } |
5975 | |
5976 | |
5977 | unsigned FormatIdx = i; |
5978 | { |
5979 | ExprResult Arg = CheckOSLogFormatStringArg(TheCall->getArg(i)); |
5980 | if (Arg.isInvalid()) |
5981 | return true; |
5982 | TheCall->setArg(i, Arg.get()); |
5983 | i++; |
5984 | } |
5985 | |
5986 | |
5987 | unsigned FirstDataArg = i; |
5988 | while (i < NumArgs) { |
5989 | ExprResult Arg = DefaultVariadicArgumentPromotion( |
5990 | TheCall->getArg(i), VariadicFunction, nullptr); |
5991 | if (Arg.isInvalid()) |
5992 | return true; |
5993 | CharUnits ArgSize = Context.getTypeSizeInChars(Arg.get()->getType()); |
5994 | if (ArgSize.getQuantity() >= 0x100) { |
5995 | return Diag(Arg.get()->getEndLoc(), diag::err_os_log_argument_too_big) |
5996 | << i << (int)ArgSize.getQuantity() << 0xff |
5997 | << TheCall->getSourceRange(); |
5998 | } |
5999 | TheCall->setArg(i, Arg.get()); |
6000 | i++; |
6001 | } |
6002 | |
6003 | |
6004 | |
6005 | if (!IsSizeCall) { |
6006 | llvm::SmallBitVector CheckedVarArgs(NumArgs, false); |
6007 | ArrayRef<const Expr *> Args(TheCall->getArgs(), TheCall->getNumArgs()); |
6008 | bool Success = CheckFormatArguments( |
6009 | Args, false, FormatIdx, FirstDataArg, FST_OSLog, |
6010 | VariadicFunction, TheCall->getBeginLoc(), SourceRange(), |
6011 | CheckedVarArgs); |
6012 | if (!Success) |
6013 | return true; |
6014 | } |
6015 | |
6016 | if (IsSizeCall) { |
6017 | TheCall->setType(Context.getSizeType()); |
6018 | } else { |
6019 | TheCall->setType(Context.VoidPtrTy); |
6020 | } |
6021 | return false; |
6022 | } |
6023 | |
6024 | |
6025 | |
6026 | bool Sema::SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, |
6027 | llvm::APSInt &Result) { |
6028 | Expr *Arg = TheCall->getArg(ArgNum); |
6029 | DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); |
6030 | FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl()); |
6031 | |
6032 | if (Arg->isTypeDependent() || Arg->isValueDependent()) return false; |
6033 | |
6034 | if (!Arg->isIntegerConstantExpr(Result, Context)) |
6035 | return Diag(TheCall->getBeginLoc(), diag::err_constant_integer_arg_type) |
6036 | << FDecl->getDeclName() << Arg->getSourceRange(); |
6037 | |
6038 | return false; |
6039 | } |
6040 | |
6041 | |
6042 | |
6043 | bool Sema::SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, |
6044 | int Low, int High, bool RangeIsError) { |
6045 | llvm::APSInt Result; |
6046 | |
6047 | |
6048 | Expr *Arg = TheCall->getArg(ArgNum); |
6049 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
6050 | return false; |
6051 | |
6052 | |
6053 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
6054 | return true; |
6055 | |
6056 | if (Result.getSExtValue() < Low || Result.getSExtValue() > High) { |
6057 | if (RangeIsError) |
6058 | return Diag(TheCall->getBeginLoc(), diag::err_argument_invalid_range) |
6059 | << Result.toString(10) << Low << High << Arg->getSourceRange(); |
6060 | else |
6061 | |
6062 | |
6063 | DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall, |
6064 | PDiag(diag::warn_argument_invalid_range) |
6065 | << Result.toString(10) << Low << High |
6066 | << Arg->getSourceRange()); |
6067 | } |
6068 | |
6069 | return false; |
6070 | } |
6071 | |
6072 | |
6073 | |
6074 | bool Sema::SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, |
6075 | unsigned Num) { |
6076 | llvm::APSInt Result; |
6077 | |
6078 | |
6079 | Expr *Arg = TheCall->getArg(ArgNum); |
6080 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
6081 | return false; |
6082 | |
6083 | |
6084 | if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) |
6085 | return true; |
6086 | |
6087 | if (Result.getSExtValue() % Num != 0) |
6088 | return Diag(TheCall->getBeginLoc(), diag::err_argument_not_multiple) |
6089 | << Num << Arg->getSourceRange(); |
6090 | |
6091 | return false; |
6092 | } |
6093 | |
6094 | |
6095 | |
6096 | bool Sema::SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, |
6097 | int ArgNum, unsigned ExpectedFieldNum, |
6098 | bool AllowName) { |
6099 | bool IsARMBuiltin = BuiltinID == ARM::BI__builtin_arm_rsr64 || |
6100 | BuiltinID == ARM::BI__builtin_arm_wsr64 || |
6101 | BuiltinID == ARM::BI__builtin_arm_rsr || |
6102 | BuiltinID == ARM::BI__builtin_arm_rsrp || |
6103 | BuiltinID == ARM::BI__builtin_arm_wsr || |
6104 | BuiltinID == ARM::BI__builtin_arm_wsrp; |
6105 | bool IsAArch64Builtin = BuiltinID == AArch64::BI__builtin_arm_rsr64 || |
6106 | BuiltinID == AArch64::BI__builtin_arm_wsr64 || |
6107 | BuiltinID == AArch64::BI__builtin_arm_rsr || |
6108 | BuiltinID == AArch64::BI__builtin_arm_rsrp || |
6109 | BuiltinID == AArch64::BI__builtin_arm_wsr || |
6110 | BuiltinID == AArch64::BI__builtin_arm_wsrp; |
6111 | (0) . __assert_fail ("(IsARMBuiltin || IsAArch64Builtin) && \"Unexpected ARM builtin.\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6111, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((IsARMBuiltin || IsAArch64Builtin) && "Unexpected ARM builtin."); |
6112 | |
6113 | |
6114 | Expr *Arg = TheCall->getArg(ArgNum); |
6115 | if (Arg->isTypeDependent() || Arg->isValueDependent()) |
6116 | return false; |
6117 | |
6118 | |
6119 | if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts())) |
6120 | return Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal) |
6121 | << Arg->getSourceRange(); |
6122 | |
6123 | |
6124 | StringRef Reg = cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString(); |
6125 | SmallVector<StringRef, 6> Fields; |
6126 | Reg.split(Fields, ":"); |
6127 | |
6128 | if (Fields.size() != ExpectedFieldNum && !(AllowName && Fields.size() == 1)) |
6129 | return Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_specialreg) |
6130 | << Arg->getSourceRange(); |
6131 | |
6132 | |
6133 | |
6134 | |
6135 | |
6136 | if (Fields.size() > 1) { |
6137 | bool FiveFields = Fields.size() == 5; |
6138 | |
6139 | bool ValidString = true; |
6140 | if (IsARMBuiltin) { |
6141 | ValidString &= Fields[0].startswith_lower("cp") || |
6142 | Fields[0].startswith_lower("p"); |
6143 | if (ValidString) |
6144 | Fields[0] = |
6145 | Fields[0].drop_front(Fields[0].startswith_lower("cp") ? 2 : 1); |
6146 | |
6147 | ValidString &= Fields[2].startswith_lower("c"); |
6148 | if (ValidString) |
6149 | Fields[2] = Fields[2].drop_front(1); |
6150 | |
6151 | if (FiveFields) { |
6152 | ValidString &= Fields[3].startswith_lower("c"); |
6153 | if (ValidString) |
6154 | Fields[3] = Fields[3].drop_front(1); |
6155 | } |
6156 | } |
6157 | |
6158 | SmallVector<int, 5> Ranges; |
6159 | if (FiveFields) |
6160 | Ranges.append({IsAArch64Builtin ? 1 : 15, 7, 15, 15, 7}); |
6161 | else |
6162 | Ranges.append({15, 7, 15}); |
6163 | |
6164 | for (unsigned i=0; i<Fields.size(); ++i) { |
6165 | int IntField; |
6166 | ValidString &= !Fields[i].getAsInteger(10, IntField); |
6167 | ValidString &= (IntField >= 0 && IntField <= Ranges[i]); |
6168 | } |
6169 | |
6170 | if (!ValidString) |
6171 | return Diag(TheCall->getBeginLoc(), diag::err_arm_invalid_specialreg) |
6172 | << Arg->getSourceRange(); |
6173 | } else if (IsAArch64Builtin && Fields.size() == 1) { |
6174 | |
6175 | |
6176 | |
6177 | |
6178 | |
6179 | |
6180 | if (TheCall->getNumArgs() != 2) |
6181 | return false; |
6182 | |
6183 | std::string RegLower = Reg.lower(); |
6184 | if (RegLower != "spsel" && RegLower != "daifset" && RegLower != "daifclr" && |
6185 | RegLower != "pan" && RegLower != "uao") |
6186 | return false; |
6187 | |
6188 | return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15); |
6189 | } |
6190 | |
6191 | return false; |
6192 | } |
6193 | |
6194 | |
6195 | |
6196 | |
6197 | bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) { |
6198 | if (!Context.getTargetInfo().hasSjLjLowering()) |
6199 | return Diag(TheCall->getBeginLoc(), diag::err_builtin_longjmp_unsupported) |
6200 | << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); |
6201 | |
6202 | Expr *Arg = TheCall->getArg(1); |
6203 | llvm::APSInt Result; |
6204 | |
6205 | |
6206 | if (SemaBuiltinConstantArg(TheCall, 1, Result)) |
6207 | return true; |
6208 | |
6209 | if (Result != 1) |
6210 | return Diag(TheCall->getBeginLoc(), diag::err_builtin_longjmp_invalid_val) |
6211 | << SourceRange(Arg->getBeginLoc(), Arg->getEndLoc()); |
6212 | |
6213 | return false; |
6214 | } |
6215 | |
6216 | |
6217 | |
6218 | bool Sema::SemaBuiltinSetjmp(CallExpr *TheCall) { |
6219 | if (!Context.getTargetInfo().hasSjLjLowering()) |
6220 | return Diag(TheCall->getBeginLoc(), diag::err_builtin_setjmp_unsupported) |
6221 | << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); |
6222 | return false; |
6223 | } |
6224 | |
6225 | namespace { |
6226 | |
6227 | class UncoveredArgHandler { |
6228 | enum { Unknown = -1, AllCovered = -2 }; |
6229 | |
6230 | signed FirstUncoveredArg = Unknown; |
6231 | SmallVector<const Expr *, 4> DiagnosticExprs; |
6232 | |
6233 | public: |
6234 | UncoveredArgHandler() = default; |
6235 | |
6236 | bool hasUncoveredArg() const { |
6237 | return (FirstUncoveredArg >= 0); |
6238 | } |
6239 | |
6240 | unsigned getUncoveredArg() const { |
6241 | (0) . __assert_fail ("hasUncoveredArg() && \"no uncovered argument\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6241, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(hasUncoveredArg() && "no uncovered argument"); |
6242 | return FirstUncoveredArg; |
6243 | } |
6244 | |
6245 | void setAllCovered() { |
6246 | |
6247 | |
6248 | DiagnosticExprs.clear(); |
6249 | FirstUncoveredArg = AllCovered; |
6250 | } |
6251 | |
6252 | void Update(signed NewFirstUncoveredArg, const Expr *StrExpr) { |
6253 | (0) . __assert_fail ("NewFirstUncoveredArg >= 0 && \"Outside range\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6253, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(NewFirstUncoveredArg >= 0 && "Outside range"); |
6254 | |
6255 | |
6256 | if (FirstUncoveredArg == AllCovered) |
6257 | return; |
6258 | |
6259 | |
6260 | |
6261 | if (NewFirstUncoveredArg == FirstUncoveredArg) |
6262 | DiagnosticExprs.push_back(StrExpr); |
6263 | else if (NewFirstUncoveredArg > FirstUncoveredArg) { |
6264 | DiagnosticExprs.clear(); |
6265 | DiagnosticExprs.push_back(StrExpr); |
6266 | FirstUncoveredArg = NewFirstUncoveredArg; |
6267 | } |
6268 | } |
6269 | |
6270 | void Diagnose(Sema &S, bool IsFunctionCall, const Expr *ArgExpr); |
6271 | }; |
6272 | |
6273 | enum StringLiteralCheckType { |
6274 | SLCT_NotALiteral, |
6275 | SLCT_UncheckedLiteral, |
6276 | SLCT_CheckedLiteral |
6277 | }; |
6278 | |
6279 | } |
6280 | |
6281 | static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, |
6282 | BinaryOperatorKind BinOpKind, |
6283 | bool AddendIsRight) { |
6284 | unsigned BitWidth = Offset.getBitWidth(); |
6285 | unsigned AddendBitWidth = Addend.getBitWidth(); |
6286 | |
6287 | if (Addend.isUnsigned()) { |
6288 | Addend = Addend.zext(++AddendBitWidth); |
6289 | Addend.setIsSigned(true); |
6290 | } |
6291 | |
6292 | if (AddendBitWidth > BitWidth) { |
6293 | Offset = Offset.sext(AddendBitWidth); |
6294 | BitWidth = AddendBitWidth; |
6295 | } else if (BitWidth > AddendBitWidth) { |
6296 | Addend = Addend.sext(BitWidth); |
6297 | } |
6298 | |
6299 | bool Ov = false; |
6300 | llvm::APSInt ResOffset = Offset; |
6301 | if (BinOpKind == BO_Add) |
6302 | ResOffset = Offset.sadd_ov(Addend, Ov); |
6303 | else { |
6304 | (0) . __assert_fail ("AddendIsRight && BinOpKind == BO_Sub && \"operator must be add or sub with addend on the right\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6305, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(AddendIsRight && BinOpKind == BO_Sub && |
6305 | (0) . __assert_fail ("AddendIsRight && BinOpKind == BO_Sub && \"operator must be add or sub with addend on the right\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6305, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "operator must be add or sub with addend on the right"); |
6306 | ResOffset = Offset.ssub_ov(Addend, Ov); |
6307 | } |
6308 | |
6309 | |
6310 | |
6311 | if (Ov) { |
6312 | (0) . __assert_fail ("BitWidth <= std..numeric_limits..max() / 2 && \"index (intermediate) result too big\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6313, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 && |
6313 | (0) . __assert_fail ("BitWidth <= std..numeric_limits..max() / 2 && \"index (intermediate) result too big\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6313, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "index (intermediate) result too big"); |
6314 | Offset = Offset.sext(2 * BitWidth); |
6315 | sumOffsets(Offset, Addend, BinOpKind, AddendIsRight); |
6316 | return; |
6317 | } |
6318 | |
6319 | Offset = ResOffset; |
6320 | } |
6321 | |
6322 | namespace { |
6323 | |
6324 | |
6325 | |
6326 | |
6327 | class FormatStringLiteral { |
6328 | const StringLiteral *FExpr; |
6329 | int64_t Offset; |
6330 | |
6331 | public: |
6332 | FormatStringLiteral(const StringLiteral *fexpr, int64_t Offset = 0) |
6333 | : FExpr(fexpr), Offset(Offset) {} |
6334 | |
6335 | StringRef getString() const { |
6336 | return FExpr->getString().drop_front(Offset); |
6337 | } |
6338 | |
6339 | unsigned getByteLength() const { |
6340 | return FExpr->getByteLength() - getCharByteWidth() * Offset; |
6341 | } |
6342 | |
6343 | unsigned getLength() const { return FExpr->getLength() - Offset; } |
6344 | unsigned getCharByteWidth() const { return FExpr->getCharByteWidth(); } |
6345 | |
6346 | StringLiteral::StringKind getKind() const { return FExpr->getKind(); } |
6347 | |
6348 | QualType getType() const { return FExpr->getType(); } |
6349 | |
6350 | bool isAscii() const { return FExpr->isAscii(); } |
6351 | bool isWide() const { return FExpr->isWide(); } |
6352 | bool isUTF8() const { return FExpr->isUTF8(); } |
6353 | bool isUTF16() const { return FExpr->isUTF16(); } |
6354 | bool isUTF32() const { return FExpr->isUTF32(); } |
6355 | bool isPascal() const { return FExpr->isPascal(); } |
6356 | |
6357 | SourceLocation getLocationOfByte( |
6358 | unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, |
6359 | const TargetInfo &Target, unsigned *StartToken = nullptr, |
6360 | unsigned *StartTokenByteOffset = nullptr) const { |
6361 | return FExpr->getLocationOfByte(ByteNo + Offset, SM, Features, Target, |
6362 | StartToken, StartTokenByteOffset); |
6363 | } |
6364 | |
6365 | SourceLocation getBeginLoc() const LLVM_READONLY { |
6366 | return FExpr->getBeginLoc().getLocWithOffset(Offset); |
6367 | } |
6368 | |
6369 | SourceLocation getEndLoc() const LLVM_READONLY { return FExpr->getEndLoc(); } |
6370 | }; |
6371 | |
6372 | } |
6373 | |
6374 | static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, |
6375 | const Expr *OrigFormatExpr, |
6376 | ArrayRef<const Expr *> Args, |
6377 | bool HasVAListArg, unsigned format_idx, |
6378 | unsigned firstDataArg, |
6379 | Sema::FormatStringType Type, |
6380 | bool inFunctionCall, |
6381 | Sema::VariadicCallType CallType, |
6382 | llvm::SmallBitVector &CheckedVarArgs, |
6383 | UncoveredArgHandler &UncoveredArg); |
6384 | |
6385 | |
6386 | |
6387 | |
6388 | |
6389 | static StringLiteralCheckType |
6390 | checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args, |
6391 | bool HasVAListArg, unsigned format_idx, |
6392 | unsigned firstDataArg, Sema::FormatStringType Type, |
6393 | Sema::VariadicCallType CallType, bool InFunctionCall, |
6394 | llvm::SmallBitVector &CheckedVarArgs, |
6395 | UncoveredArgHandler &UncoveredArg, |
6396 | llvm::APSInt Offset) { |
6397 | tryAgain: |
6398 | (0) . __assert_fail ("Offset.isSigned() && \"invalid offset\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6398, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Offset.isSigned() && "invalid offset"); |
6399 | |
6400 | if (E->isTypeDependent() || E->isValueDependent()) |
6401 | return SLCT_NotALiteral; |
6402 | |
6403 | E = E->IgnoreParenCasts(); |
6404 | |
6405 | if (E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull)) |
6406 | |
6407 | |
6408 | |
6409 | |
6410 | return SLCT_UncheckedLiteral; |
6411 | |
6412 | switch (E->getStmtClass()) { |
6413 | case Stmt::BinaryConditionalOperatorClass: |
6414 | case Stmt::ConditionalOperatorClass: { |
6415 | |
6416 | |
6417 | const AbstractConditionalOperator *C = |
6418 | cast<AbstractConditionalOperator>(E); |
6419 | |
6420 | |
6421 | |
6422 | |
6423 | bool CheckLeft = true, CheckRight = true; |
6424 | |
6425 | bool Cond; |
6426 | if (C->getCond()->EvaluateAsBooleanCondition(Cond, S.getASTContext())) { |
6427 | if (Cond) |
6428 | CheckRight = false; |
6429 | else |
6430 | CheckLeft = false; |
6431 | } |
6432 | |
6433 | |
6434 | |
6435 | |
6436 | |
6437 | StringLiteralCheckType Left; |
6438 | if (!CheckLeft) |
6439 | Left = SLCT_UncheckedLiteral; |
6440 | else { |
6441 | Left = checkFormatStringExpr(S, C->getTrueExpr(), Args, |
6442 | HasVAListArg, format_idx, firstDataArg, |
6443 | Type, CallType, InFunctionCall, |
6444 | CheckedVarArgs, UncoveredArg, Offset); |
6445 | if (Left == SLCT_NotALiteral || !CheckRight) { |
6446 | return Left; |
6447 | } |
6448 | } |
6449 | |
6450 | StringLiteralCheckType Right = |
6451 | checkFormatStringExpr(S, C->getFalseExpr(), Args, |
6452 | HasVAListArg, format_idx, firstDataArg, |
6453 | Type, CallType, InFunctionCall, CheckedVarArgs, |
6454 | UncoveredArg, Offset); |
6455 | |
6456 | return (CheckLeft && Left < Right) ? Left : Right; |
6457 | } |
6458 | |
6459 | case Stmt::ImplicitCastExprClass: |
6460 | E = cast<ImplicitCastExpr>(E)->getSubExpr(); |
6461 | goto tryAgain; |
6462 | |
6463 | case Stmt::OpaqueValueExprClass: |
6464 | if (const Expr *src = cast<OpaqueValueExpr>(E)->getSourceExpr()) { |
6465 | E = src; |
6466 | goto tryAgain; |
6467 | } |
6468 | return SLCT_NotALiteral; |
6469 | |
6470 | case Stmt::PredefinedExprClass: |
6471 | |
6472 | |
6473 | |
6474 | return SLCT_UncheckedLiteral; |
6475 | |
6476 | case Stmt::DeclRefExprClass: { |
6477 | const DeclRefExpr *DR = cast<DeclRefExpr>(E); |
6478 | |
6479 | |
6480 | |
6481 | if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { |
6482 | bool isConstant = false; |
6483 | QualType T = DR->getType(); |
6484 | |
6485 | if (const ArrayType *AT = S.Context.getAsArrayType(T)) { |
6486 | isConstant = AT->getElementType().isConstant(S.Context); |
6487 | } else if (const PointerType *PT = T->getAs<PointerType>()) { |
6488 | isConstant = T.isConstant(S.Context) && |
6489 | PT->getPointeeType().isConstant(S.Context); |
6490 | } else if (T->isObjCObjectPointerType()) { |
6491 | |
6492 | |
6493 | isConstant = T.isConstant(S.Context); |
6494 | } |
6495 | |
6496 | if (isConstant) { |
6497 | if (const Expr *Init = VD->getAnyInitializer()) { |
6498 | |
6499 | if (const InitListExpr *InitList = dyn_cast<InitListExpr>(Init)) { |
6500 | if (InitList->isStringLiteralInit()) |
6501 | Init = InitList->getInit(0)->IgnoreParenImpCasts(); |
6502 | } |
6503 | return checkFormatStringExpr(S, Init, Args, |
6504 | HasVAListArg, format_idx, |
6505 | firstDataArg, Type, CallType, |
6506 | false, CheckedVarArgs, |
6507 | UncoveredArg, Offset); |
6508 | } |
6509 | } |
6510 | |
6511 | |
6512 | |
6513 | |
6514 | |
6515 | |
6516 | |
6517 | |
6518 | |
6519 | |
6520 | |
6521 | |
6522 | |
6523 | |
6524 | |
6525 | if (HasVAListArg) { |
6526 | if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(VD)) { |
6527 | if (const NamedDecl *ND = dyn_cast<NamedDecl>(PV->getDeclContext())) { |
6528 | int PVIndex = PV->getFunctionScopeIndex() + 1; |
6529 | for (const auto *PVFormat : ND->specific_attrs<FormatAttr>()) { |
6530 | |
6531 | if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND)) |
6532 | if (MD->isInstance()) |
6533 | ++PVIndex; |
6534 | |
6535 | |
6536 | if (PVIndex == PVFormat->getFormatIdx() && |
6537 | Type == S.GetFormatStringType(PVFormat)) |
6538 | return SLCT_UncheckedLiteral; |
6539 | } |
6540 | } |
6541 | } |
6542 | } |
6543 | } |
6544 | |
6545 | return SLCT_NotALiteral; |
6546 | } |
6547 | |
6548 | case Stmt::CallExprClass: |
6549 | case Stmt::CXXMemberCallExprClass: { |
6550 | const CallExpr *CE = cast<CallExpr>(E); |
6551 | if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) { |
6552 | bool IsFirst = true; |
6553 | StringLiteralCheckType CommonResult; |
6554 | for (const auto *FA : ND->specific_attrs<FormatArgAttr>()) { |
6555 | const Expr *Arg = CE->getArg(FA->getFormatIdx().getASTIndex()); |
6556 | StringLiteralCheckType Result = checkFormatStringExpr( |
6557 | S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type, |
6558 | CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset); |
6559 | if (IsFirst) { |
6560 | CommonResult = Result; |
6561 | IsFirst = false; |
6562 | } |
6563 | } |
6564 | if (!IsFirst) |
6565 | return CommonResult; |
6566 | |
6567 | if (const auto *FD = dyn_cast<FunctionDecl>(ND)) { |
6568 | unsigned BuiltinID = FD->getBuiltinID(); |
6569 | if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString || |
6570 | BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) { |
6571 | const Expr *Arg = CE->getArg(0); |
6572 | return checkFormatStringExpr(S, Arg, Args, |
6573 | HasVAListArg, format_idx, |
6574 | firstDataArg, Type, CallType, |
6575 | InFunctionCall, CheckedVarArgs, |
6576 | UncoveredArg, Offset); |
6577 | } |
6578 | } |
6579 | } |
6580 | |
6581 | return SLCT_NotALiteral; |
6582 | } |
6583 | case Stmt::ObjCMessageExprClass: { |
6584 | const auto *ME = cast<ObjCMessageExpr>(E); |
6585 | if (const auto *ND = ME->getMethodDecl()) { |
6586 | if (const auto *FA = ND->getAttr<FormatArgAttr>()) { |
6587 | const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex()); |
6588 | return checkFormatStringExpr( |
6589 | S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type, |
6590 | CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset); |
6591 | } |
6592 | } |
6593 | |
6594 | return SLCT_NotALiteral; |
6595 | } |
6596 | case Stmt::ObjCStringLiteralClass: |
6597 | case Stmt::StringLiteralClass: { |
6598 | const StringLiteral *StrE = nullptr; |
6599 | |
6600 | if (const ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(E)) |
6601 | StrE = ObjCFExpr->getString(); |
6602 | else |
6603 | StrE = cast<StringLiteral>(E); |
6604 | |
6605 | if (StrE) { |
6606 | if (Offset.isNegative() || Offset > StrE->getLength()) { |
6607 | |
6608 | |
6609 | return SLCT_NotALiteral; |
6610 | } |
6611 | FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue()); |
6612 | CheckFormatString(S, &FStr, E, Args, HasVAListArg, format_idx, |
6613 | firstDataArg, Type, InFunctionCall, CallType, |
6614 | CheckedVarArgs, UncoveredArg); |
6615 | return SLCT_CheckedLiteral; |
6616 | } |
6617 | |
6618 | return SLCT_NotALiteral; |
6619 | } |
6620 | case Stmt::BinaryOperatorClass: { |
6621 | const BinaryOperator *BinOp = cast<BinaryOperator>(E); |
6622 | |
6623 | |
6624 | if (BinOp->isAdditiveOp()) { |
6625 | Expr::EvalResult LResult, RResult; |
6626 | |
6627 | bool LIsInt = BinOp->getLHS()->EvaluateAsInt(LResult, S.Context); |
6628 | bool RIsInt = BinOp->getRHS()->EvaluateAsInt(RResult, S.Context); |
6629 | |
6630 | if (LIsInt != RIsInt) { |
6631 | BinaryOperatorKind BinOpKind = BinOp->getOpcode(); |
6632 | |
6633 | if (LIsInt) { |
6634 | if (BinOpKind == BO_Add) { |
6635 | sumOffsets(Offset, LResult.Val.getInt(), BinOpKind, RIsInt); |
6636 | E = BinOp->getRHS(); |
6637 | goto tryAgain; |
6638 | } |
6639 | } else { |
6640 | sumOffsets(Offset, RResult.Val.getInt(), BinOpKind, RIsInt); |
6641 | E = BinOp->getLHS(); |
6642 | goto tryAgain; |
6643 | } |
6644 | } |
6645 | } |
6646 | |
6647 | return SLCT_NotALiteral; |
6648 | } |
6649 | case Stmt::UnaryOperatorClass: { |
6650 | const UnaryOperator *UnaOp = cast<UnaryOperator>(E); |
6651 | auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->getSubExpr()); |
6652 | if (UnaOp->getOpcode() == UO_AddrOf && ASE) { |
6653 | Expr::EvalResult IndexResult; |
6654 | if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.Context)) { |
6655 | sumOffsets(Offset, IndexResult.Val.getInt(), BO_Add, |
6656 | true); |
6657 | E = ASE->getBase(); |
6658 | goto tryAgain; |
6659 | } |
6660 | } |
6661 | |
6662 | return SLCT_NotALiteral; |
6663 | } |
6664 | |
6665 | default: |
6666 | return SLCT_NotALiteral; |
6667 | } |
6668 | } |
6669 | |
6670 | Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) { |
6671 | return llvm::StringSwitch<FormatStringType>(Format->getType()->getName()) |
6672 | .Case("scanf", FST_Scanf) |
6673 | .Cases("printf", "printf0", FST_Printf) |
6674 | .Cases("NSString", "CFString", FST_NSString) |
6675 | .Case("strftime", FST_Strftime) |
6676 | .Case("strfmon", FST_Strfmon) |
6677 | .Cases("kprintf", "cmn_err", "vcmn_err", "zcmn_err", FST_Kprintf) |
6678 | .Case("freebsd_kprintf", FST_FreeBSDKPrintf) |
6679 | .Case("os_trace", FST_OSLog) |
6680 | .Case("os_log", FST_OSLog) |
6681 | .Default(FST_Unknown); |
6682 | } |
6683 | |
6684 | |
6685 | |
6686 | |
6687 | bool Sema::CheckFormatArguments(const FormatAttr *Format, |
6688 | ArrayRef<const Expr *> Args, |
6689 | bool IsCXXMember, |
6690 | VariadicCallType CallType, |
6691 | SourceLocation Loc, SourceRange Range, |
6692 | llvm::SmallBitVector &CheckedVarArgs) { |
6693 | FormatStringInfo FSI; |
6694 | if (getFormatStringInfo(Format, IsCXXMember, &FSI)) |
6695 | return CheckFormatArguments(Args, FSI.HasVAListArg, FSI.FormatIdx, |
6696 | FSI.FirstDataArg, GetFormatStringType(Format), |
6697 | CallType, Loc, Range, CheckedVarArgs); |
6698 | return false; |
6699 | } |
6700 | |
6701 | bool Sema::CheckFormatArguments(ArrayRef<const Expr *> Args, |
6702 | bool HasVAListArg, unsigned format_idx, |
6703 | unsigned firstDataArg, FormatStringType Type, |
6704 | VariadicCallType CallType, |
6705 | SourceLocation Loc, SourceRange Range, |
6706 | llvm::SmallBitVector &CheckedVarArgs) { |
6707 | |
6708 | if (format_idx >= Args.size()) { |
6709 | Diag(Loc, diag::warn_missing_format_string) << Range; |
6710 | return false; |
6711 | } |
6712 | |
6713 | const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts(); |
6714 | |
6715 | |
6716 | |
6717 | |
6718 | |
6719 | |
6720 | |
6721 | |
6722 | |
6723 | |
6724 | |
6725 | |
6726 | |
6727 | UncoveredArgHandler UncoveredArg; |
6728 | StringLiteralCheckType CT = |
6729 | checkFormatStringExpr(*this, OrigFormatExpr, Args, HasVAListArg, |
6730 | format_idx, firstDataArg, Type, CallType, |
6731 | true, CheckedVarArgs, |
6732 | UncoveredArg, |
6733 | llvm::APSInt(64, false) = 0); |
6734 | |
6735 | |
6736 | if (UncoveredArg.hasUncoveredArg()) { |
6737 | unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg; |
6738 | (0) . __assert_fail ("ArgIdx < Args.size() && \"ArgIdx outside bounds\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 6738, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ArgIdx < Args.size() && "ArgIdx outside bounds"); |
6739 | UncoveredArg.Diagnose(*this, , Args[ArgIdx]); |
6740 | } |
6741 | |
6742 | if (CT != SLCT_NotALiteral) |
6743 | |
6744 | return CT == SLCT_CheckedLiteral; |
6745 | |
6746 | |
6747 | |
6748 | if (Type == FST_Strftime) |
6749 | return false; |
6750 | |
6751 | |
6752 | |
6753 | |
6754 | |
6755 | SourceLocation FormatLoc = Args[format_idx]->getBeginLoc(); |
6756 | if (Type == FST_NSString && SourceMgr.isInSystemMacro(FormatLoc)) |
6757 | return false; |
6758 | |
6759 | |
6760 | |
6761 | if (Args.size() == firstDataArg) { |
6762 | Diag(FormatLoc, diag::warn_format_nonliteral_noargs) |
6763 | << OrigFormatExpr->getSourceRange(); |
6764 | switch (Type) { |
6765 | default: |
6766 | break; |
6767 | case FST_Kprintf: |
6768 | case FST_FreeBSDKPrintf: |
6769 | case FST_Printf: |
6770 | Diag(FormatLoc, diag::note_format_security_fixit) |
6771 | << FixItHint::CreateInsertion(FormatLoc, "\"%s\", "); |
6772 | break; |
6773 | case FST_NSString: |
6774 | Diag(FormatLoc, diag::note_format_security_fixit) |
6775 | << FixItHint::CreateInsertion(FormatLoc, "@\"%@\", "); |
6776 | break; |
6777 | } |
6778 | } else { |
6779 | Diag(FormatLoc, diag::warn_format_nonliteral) |
6780 | << OrigFormatExpr->getSourceRange(); |
6781 | } |
6782 | return false; |
6783 | } |
6784 | |
6785 | namespace { |
6786 | |
6787 | class CheckFormatHandler : public analyze_format_string::FormatStringHandler { |
6788 | protected: |
6789 | Sema &S; |
6790 | const FormatStringLiteral *FExpr; |
6791 | const Expr *OrigFormatExpr; |
6792 | const Sema::FormatStringType FSType; |
6793 | const unsigned FirstDataArg; |
6794 | const unsigned NumDataArgs; |
6795 | const char *Beg; |
6796 | const bool HasVAListArg; |
6797 | ArrayRef<const Expr *> Args; |
6798 | unsigned FormatIdx; |
6799 | llvm::SmallBitVector CoveredArgs; |
6800 | bool usesPositionalArgs = false; |
6801 | bool atFirstArg = true; |
6802 | bool inFunctionCall; |
6803 | Sema::VariadicCallType CallType; |
6804 | llvm::SmallBitVector &CheckedVarArgs; |
6805 | UncoveredArgHandler &UncoveredArg; |
6806 | |
6807 | public: |
6808 | CheckFormatHandler(Sema &s, const FormatStringLiteral *fexpr, |
6809 | const Expr *origFormatExpr, |
6810 | const Sema::FormatStringType type, unsigned firstDataArg, |
6811 | unsigned numDataArgs, const char *beg, bool hasVAListArg, |
6812 | ArrayRef<const Expr *> Args, unsigned formatIdx, |
6813 | bool inFunctionCall, Sema::VariadicCallType callType, |
6814 | llvm::SmallBitVector &CheckedVarArgs, |
6815 | UncoveredArgHandler &UncoveredArg) |
6816 | : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(type), |
6817 | FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg), |
6818 | HasVAListArg(hasVAListArg), Args(Args), FormatIdx(formatIdx), |
6819 | inFunctionCall(inFunctionCall), CallType(callType), |
6820 | CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) { |
6821 | CoveredArgs.resize(numDataArgs); |
6822 | CoveredArgs.reset(); |
6823 | } |
6824 | |
6825 | void DoneProcessing(); |
6826 | |
6827 | void HandleIncompleteSpecifier(const char *startSpecifier, |
6828 | unsigned specifierLen) override; |
6829 | |
6830 | void HandleInvalidLengthModifier( |
6831 | const analyze_format_string::FormatSpecifier &FS, |
6832 | const analyze_format_string::ConversionSpecifier &CS, |
6833 | const char *startSpecifier, unsigned specifierLen, |
6834 | unsigned DiagID); |
6835 | |
6836 | void HandleNonStandardLengthModifier( |
6837 | const analyze_format_string::FormatSpecifier &FS, |
6838 | const char *startSpecifier, unsigned specifierLen); |
6839 | |
6840 | void HandleNonStandardConversionSpecifier( |
6841 | const analyze_format_string::ConversionSpecifier &CS, |
6842 | const char *startSpecifier, unsigned specifierLen); |
6843 | |
6844 | void HandlePosition(const char *startPos, unsigned posLen) override; |
6845 | |
6846 | void HandleInvalidPosition(const char *startSpecifier, |
6847 | unsigned specifierLen, |
6848 | analyze_format_string::PositionContext p) override; |
6849 | |
6850 | void HandleZeroPosition(const char *startPos, unsigned posLen) override; |
6851 | |
6852 | void HandleNullChar(const char *nullCharacter) override; |
6853 | |
6854 | template <typename Range> |
6855 | static void |
6856 | EmitFormatDiagnostic(Sema &S, bool inFunctionCall, const Expr *ArgumentExpr, |
6857 | const PartialDiagnostic &PDiag, SourceLocation StringLoc, |
6858 | bool IsStringLocation, Range StringRange, |
6859 | ArrayRef<FixItHint> Fixit = None); |
6860 | |
6861 | protected: |
6862 | bool HandleInvalidConversionSpecifier(unsigned argIndex, SourceLocation Loc, |
6863 | const char *startSpec, |
6864 | unsigned specifierLen, |
6865 | const char *csStart, unsigned csLen); |
6866 | |
6867 | void HandlePositionalNonpositionalArgs(SourceLocation Loc, |
6868 | const char *startSpec, |
6869 | unsigned specifierLen); |
6870 | |
6871 | SourceRange getFormatStringRange(); |
6872 | CharSourceRange getSpecifierRange(const char *startSpecifier, |
6873 | unsigned specifierLen); |
6874 | SourceLocation getLocationOfByte(const char *x); |
6875 | |
6876 | const Expr *getDataArg(unsigned i) const; |
6877 | |
6878 | bool CheckNumArgs(const analyze_format_string::FormatSpecifier &FS, |
6879 | const analyze_format_string::ConversionSpecifier &CS, |
6880 | const char *startSpecifier, unsigned specifierLen, |
6881 | unsigned argIndex); |
6882 | |
6883 | template <typename Range> |
6884 | void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc, |
6885 | bool IsStringLocation, Range StringRange, |
6886 | ArrayRef<FixItHint> Fixit = None); |
6887 | }; |
6888 | |
6889 | } |
6890 | |
6891 | SourceRange CheckFormatHandler::getFormatStringRange() { |
6892 | return OrigFormatExpr->getSourceRange(); |
6893 | } |
6894 | |
6895 | CharSourceRange CheckFormatHandler:: |
6896 | getSpecifierRange(const char *startSpecifier, unsigned specifierLen) { |
6897 | SourceLocation Start = getLocationOfByte(startSpecifier); |
6898 | SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1); |
6899 | |
6900 | |
6901 | End = End.getLocWithOffset(1); |
6902 | |
6903 | return CharSourceRange::getCharRange(Start, End); |
6904 | } |
6905 | |
6906 | SourceLocation CheckFormatHandler::getLocationOfByte(const char *x) { |
6907 | return FExpr->getLocationOfByte(x - Beg, S.getSourceManager(), |
6908 | S.getLangOpts(), S.Context.getTargetInfo()); |
6909 | } |
6910 | |
6911 | void CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier, |
6912 | unsigned specifierLen){ |
6913 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_incomplete_specifier), |
6914 | getLocationOfByte(startSpecifier), |
6915 | , |
6916 | getSpecifierRange(startSpecifier, specifierLen)); |
6917 | } |
6918 | |
6919 | void CheckFormatHandler::HandleInvalidLengthModifier( |
6920 | const analyze_format_string::FormatSpecifier &FS, |
6921 | const analyze_format_string::ConversionSpecifier &CS, |
6922 | const char *startSpecifier, unsigned specifierLen, unsigned DiagID) { |
6923 | using namespace analyze_format_string; |
6924 | |
6925 | const LengthModifier &LM = FS.getLengthModifier(); |
6926 | CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength()); |
6927 | |
6928 | |
6929 | Optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier(); |
6930 | if (FixedLM) { |
6931 | EmitFormatDiagnostic(S.PDiag(DiagID) << LM.toString() << CS.toString(), |
6932 | getLocationOfByte(LM.getStart()), |
6933 | , |
6934 | getSpecifierRange(startSpecifier, specifierLen)); |
6935 | |
6936 | S.Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier) |
6937 | << FixedLM->toString() |
6938 | << FixItHint::CreateReplacement(LMRange, FixedLM->toString()); |
6939 | |
6940 | } else { |
6941 | FixItHint Hint; |
6942 | if (DiagID == diag::warn_format_nonsensical_length) |
6943 | Hint = FixItHint::CreateRemoval(LMRange); |
6944 | |
6945 | EmitFormatDiagnostic(S.PDiag(DiagID) << LM.toString() << CS.toString(), |
6946 | getLocationOfByte(LM.getStart()), |
6947 | , |
6948 | getSpecifierRange(startSpecifier, specifierLen), |
6949 | Hint); |
6950 | } |
6951 | } |
6952 | |
6953 | void CheckFormatHandler::HandleNonStandardLengthModifier( |
6954 | const analyze_format_string::FormatSpecifier &FS, |
6955 | const char *startSpecifier, unsigned specifierLen) { |
6956 | using namespace analyze_format_string; |
6957 | |
6958 | const LengthModifier &LM = FS.getLengthModifier(); |
6959 | CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength()); |
6960 | |
6961 | |
6962 | Optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier(); |
6963 | if (FixedLM) { |
6964 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) |
6965 | << LM.toString() << 0, |
6966 | getLocationOfByte(LM.getStart()), |
6967 | , |
6968 | getSpecifierRange(startSpecifier, specifierLen)); |
6969 | |
6970 | S.Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier) |
6971 | << FixedLM->toString() |
6972 | << FixItHint::CreateReplacement(LMRange, FixedLM->toString()); |
6973 | |
6974 | } else { |
6975 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) |
6976 | << LM.toString() << 0, |
6977 | getLocationOfByte(LM.getStart()), |
6978 | , |
6979 | getSpecifierRange(startSpecifier, specifierLen)); |
6980 | } |
6981 | } |
6982 | |
6983 | void CheckFormatHandler::HandleNonStandardConversionSpecifier( |
6984 | const analyze_format_string::ConversionSpecifier &CS, |
6985 | const char *startSpecifier, unsigned specifierLen) { |
6986 | using namespace analyze_format_string; |
6987 | |
6988 | |
6989 | Optional<ConversionSpecifier> FixedCS = CS.getStandardSpecifier(); |
6990 | if (FixedCS) { |
6991 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) |
6992 | << CS.toString() << , |
6993 | getLocationOfByte(CS.getStart()), |
6994 | , |
6995 | getSpecifierRange(startSpecifier, specifierLen)); |
6996 | |
6997 | CharSourceRange CSRange = getSpecifierRange(CS.getStart(), CS.getLength()); |
6998 | S.Diag(getLocationOfByte(CS.getStart()), diag::note_format_fix_specifier) |
6999 | << FixedCS->toString() |
7000 | << FixItHint::CreateReplacement(CSRange, FixedCS->toString()); |
7001 | } else { |
7002 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) |
7003 | << CS.toString() << , |
7004 | getLocationOfByte(CS.getStart()), |
7005 | , |
7006 | getSpecifierRange(startSpecifier, specifierLen)); |
7007 | } |
7008 | } |
7009 | |
7010 | void CheckFormatHandler::HandlePosition(const char *startPos, |
7011 | unsigned posLen) { |
7012 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard_positional_arg), |
7013 | getLocationOfByte(startPos), |
7014 | , |
7015 | getSpecifierRange(startPos, posLen)); |
7016 | } |
7017 | |
7018 | void |
7019 | CheckFormatHandler::HandleInvalidPosition(const char *startPos, unsigned posLen, |
7020 | analyze_format_string::PositionContext p) { |
7021 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_invalid_positional_specifier) |
7022 | << (unsigned) p, |
7023 | getLocationOfByte(startPos), , |
7024 | getSpecifierRange(startPos, posLen)); |
7025 | } |
7026 | |
7027 | void CheckFormatHandler::HandleZeroPosition(const char *startPos, |
7028 | unsigned posLen) { |
7029 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_zero_positional_specifier), |
7030 | getLocationOfByte(startPos), |
7031 | , |
7032 | getSpecifierRange(startPos, posLen)); |
7033 | } |
7034 | |
7035 | void CheckFormatHandler::HandleNullChar(const char *nullCharacter) { |
7036 | if (!isa<ObjCStringLiteral>(OrigFormatExpr)) { |
7037 | |
7038 | EmitFormatDiagnostic( |
7039 | S.PDiag(diag::warn_printf_format_string_contains_null_char), |
7040 | getLocationOfByte(nullCharacter), , |
7041 | getFormatStringRange()); |
7042 | } |
7043 | } |
7044 | |
7045 | |
7046 | |
7047 | const Expr *CheckFormatHandler::getDataArg(unsigned i) const { |
7048 | return Args[FirstDataArg + i]; |
7049 | } |
7050 | |
7051 | void CheckFormatHandler::DoneProcessing() { |
7052 | |
7053 | |
7054 | if (!HasVAListArg) { |
7055 | |
7056 | CoveredArgs.flip(); |
7057 | signed notCoveredArg = CoveredArgs.find_first(); |
7058 | if (notCoveredArg >= 0) { |
7059 | assert((unsigned)notCoveredArg < NumDataArgs); |
7060 | UncoveredArg.Update(notCoveredArg, OrigFormatExpr); |
7061 | } else { |
7062 | UncoveredArg.setAllCovered(); |
7063 | } |
7064 | } |
7065 | } |
7066 | |
7067 | void UncoveredArgHandler::Diagnose(Sema &S, bool IsFunctionCall, |
7068 | const Expr *ArgExpr) { |
7069 | (0) . __assert_fail ("hasUncoveredArg() && DiagnosticExprs.size() > 0 && \"Invalid state\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 7070, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(hasUncoveredArg() && DiagnosticExprs.size() > 0 && |
7070 | (0) . __assert_fail ("hasUncoveredArg() && DiagnosticExprs.size() > 0 && \"Invalid state\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 7070, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid state"); |
7071 | |
7072 | if (!ArgExpr) |
7073 | return; |
7074 | |
7075 | SourceLocation Loc = ArgExpr->getBeginLoc(); |
7076 | |
7077 | if (S.getSourceManager().isInSystemMacro(Loc)) |
7078 | return; |
7079 | |
7080 | PartialDiagnostic PDiag = S.PDiag(diag::warn_printf_data_arg_not_used); |
7081 | for (auto E : DiagnosticExprs) |
7082 | PDiag << E->getSourceRange(); |
7083 | |
7084 | CheckFormatHandler::EmitFormatDiagnostic( |
7085 | S, IsFunctionCall, DiagnosticExprs[0], |
7086 | PDiag, Loc, , |
7087 | DiagnosticExprs[0]->getSourceRange()); |
7088 | } |
7089 | |
7090 | bool |
7091 | CheckFormatHandler::HandleInvalidConversionSpecifier(unsigned argIndex, |
7092 | SourceLocation Loc, |
7093 | const char *startSpec, |
7094 | unsigned specifierLen, |
7095 | const char *csStart, |
7096 | unsigned csLen) { |
7097 | bool keepGoing = true; |
7098 | if (argIndex < NumDataArgs) { |
7099 | |
7100 | |
7101 | CoveredArgs.set(argIndex); |
7102 | } |
7103 | else { |
7104 | |
7105 | |
7106 | |
7107 | |
7108 | |
7109 | keepGoing = false; |
7110 | } |
7111 | |
7112 | StringRef Specifier(csStart, csLen); |
7113 | |
7114 | |
7115 | |
7116 | |
7117 | std::string CodePointStr; |
7118 | if (!llvm::sys::locale::isPrint(*csStart)) { |
7119 | llvm::UTF32 CodePoint; |
7120 | const llvm::UTF8 **B = reinterpret_cast<const llvm::UTF8 **>(&csStart); |
7121 | const llvm::UTF8 *E = |
7122 | reinterpret_cast<const llvm::UTF8 *>(csStart + csLen); |
7123 | llvm::ConversionResult Result = |
7124 | llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion); |
7125 | |
7126 | if (Result != llvm::conversionOK) { |
7127 | unsigned char FirstChar = *csStart; |
7128 | CodePoint = (llvm::UTF32)FirstChar; |
7129 | } |
7130 | |
7131 | llvm::raw_string_ostream OS(CodePointStr); |
7132 | if (CodePoint < 256) |
7133 | OS << "\\x" << llvm::format("%02x", CodePoint); |
7134 | else if (CodePoint <= 0xFFFF) |
7135 | OS << "\\u" << llvm::format("%04x", CodePoint); |
7136 | else |
7137 | OS << "\\U" << llvm::format("%08x", CodePoint); |
7138 | OS.flush(); |
7139 | Specifier = CodePointStr; |
7140 | } |
7141 | |
7142 | EmitFormatDiagnostic( |
7143 | S.PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc, |
7144 | true, getSpecifierRange(startSpec, specifierLen)); |
7145 | |
7146 | return keepGoing; |
7147 | } |
7148 | |
7149 | void |
7150 | CheckFormatHandler::HandlePositionalNonpositionalArgs(SourceLocation Loc, |
7151 | const char *startSpec, |
7152 | unsigned specifierLen) { |
7153 | EmitFormatDiagnostic( |
7154 | S.PDiag(diag::warn_format_mix_positional_nonpositional_args), |
7155 | Loc, , getSpecifierRange(startSpec, specifierLen)); |
7156 | } |
7157 | |
7158 | bool |
7159 | CheckFormatHandler::CheckNumArgs( |
7160 | const analyze_format_string::FormatSpecifier &FS, |
7161 | const analyze_format_string::ConversionSpecifier &CS, |
7162 | const char *startSpecifier, unsigned specifierLen, unsigned argIndex) { |
7163 | |
7164 | if (argIndex >= NumDataArgs) { |
7165 | PartialDiagnostic PDiag = FS.usesPositionalArg() |
7166 | ? (S.PDiag(diag::warn_printf_positional_arg_exceeds_data_args) |
7167 | << (argIndex+1) << NumDataArgs) |
7168 | : S.PDiag(diag::warn_printf_insufficient_data_args); |
7169 | EmitFormatDiagnostic( |
7170 | PDiag, getLocationOfByte(CS.getStart()), , |
7171 | getSpecifierRange(startSpecifier, specifierLen)); |
7172 | |
7173 | |
7174 | |
7175 | UncoveredArg.setAllCovered(); |
7176 | return false; |
7177 | } |
7178 | return true; |
7179 | } |
7180 | |
7181 | template<typename Range> |
7182 | void CheckFormatHandler::EmitFormatDiagnostic(PartialDiagnostic PDiag, |
7183 | SourceLocation Loc, |
7184 | bool IsStringLocation, |
7185 | Range StringRange, |
7186 | ArrayRef<FixItHint> FixIt) { |
7187 | EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, |
7188 | Loc, IsStringLocation, StringRange, FixIt); |
7189 | } |
7190 | |
7191 | |
7192 | |
7193 | |
7194 | |
7195 | |
7196 | |
7197 | |
7198 | |
7199 | |
7200 | |
7201 | |
7202 | |
7203 | |
7204 | |
7205 | |
7206 | |
7207 | |
7208 | |
7209 | |
7210 | |
7211 | |
7212 | |
7213 | |
7214 | |
7215 | |
7216 | |
7217 | |
7218 | template <typename Range> |
7219 | void CheckFormatHandler::EmitFormatDiagnostic( |
7220 | Sema &S, bool InFunctionCall, const Expr *ArgumentExpr, |
7221 | const PartialDiagnostic &PDiag, SourceLocation Loc, bool IsStringLocation, |
7222 | Range StringRange, ArrayRef<FixItHint> FixIt) { |
7223 | if (InFunctionCall) { |
7224 | const Sema::SemaDiagnosticBuilder &D = S.Diag(Loc, PDiag); |
7225 | D << StringRange; |
7226 | D << FixIt; |
7227 | } else { |
7228 | S.Diag(IsStringLocation ? ArgumentExpr->getExprLoc() : Loc, PDiag) |
7229 | << ArgumentExpr->getSourceRange(); |
7230 | |
7231 | const Sema::SemaDiagnosticBuilder &Note = |
7232 | S.Diag(IsStringLocation ? Loc : StringRange.getBegin(), |
7233 | diag::note_format_string_defined); |
7234 | |
7235 | Note << StringRange; |
7236 | Note << FixIt; |
7237 | } |
7238 | } |
7239 | |
7240 | |
7241 | |
7242 | namespace { |
7243 | |
7244 | class CheckPrintfHandler : public CheckFormatHandler { |
7245 | public: |
7246 | CheckPrintfHandler(Sema &s, const FormatStringLiteral *fexpr, |
7247 | const Expr *origFormatExpr, |
7248 | const Sema::FormatStringType type, unsigned firstDataArg, |
7249 | unsigned numDataArgs, bool isObjC, const char *beg, |
7250 | bool hasVAListArg, ArrayRef<const Expr *> Args, |
7251 | unsigned formatIdx, bool inFunctionCall, |
7252 | Sema::VariadicCallType CallType, |
7253 | llvm::SmallBitVector &CheckedVarArgs, |
7254 | UncoveredArgHandler &UncoveredArg) |
7255 | : CheckFormatHandler(s, fexpr, origFormatExpr, type, firstDataArg, |
7256 | numDataArgs, beg, hasVAListArg, Args, formatIdx, |
7257 | inFunctionCall, CallType, CheckedVarArgs, |
7258 | UncoveredArg) {} |
7259 | |
7260 | bool isObjCContext() const { return FSType == Sema::FST_NSString; } |
7261 | |
7262 | |
7263 | bool allowsObjCArg() const { |
7264 | return FSType == Sema::FST_NSString || FSType == Sema::FST_OSLog || |
7265 | FSType == Sema::FST_OSTrace; |
7266 | } |
7267 | |
7268 | bool HandleInvalidPrintfConversionSpecifier( |
7269 | const analyze_printf::PrintfSpecifier &FS, |
7270 | const char *startSpecifier, |
7271 | unsigned specifierLen) override; |
7272 | |
7273 | void handleInvalidMaskType(StringRef MaskType) override; |
7274 | |
7275 | bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, |
7276 | const char *startSpecifier, |
7277 | unsigned specifierLen) override; |
7278 | bool checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, |
7279 | const char *StartSpecifier, |
7280 | unsigned SpecifierLen, |
7281 | const Expr *E); |
7282 | |
7283 | bool HandleAmount(const analyze_format_string::OptionalAmount &Amt, unsigned k, |
7284 | const char *startSpecifier, unsigned specifierLen); |
7285 | void HandleInvalidAmount(const analyze_printf::PrintfSpecifier &FS, |
7286 | const analyze_printf::OptionalAmount &Amt, |
7287 | unsigned type, |
7288 | const char *startSpecifier, unsigned specifierLen); |
7289 | void HandleFlag(const analyze_printf::PrintfSpecifier &FS, |
7290 | const analyze_printf::OptionalFlag &flag, |
7291 | const char *startSpecifier, unsigned specifierLen); |
7292 | void HandleIgnoredFlag(const analyze_printf::PrintfSpecifier &FS, |
7293 | const analyze_printf::OptionalFlag &ignoredFlag, |
7294 | const analyze_printf::OptionalFlag &flag, |
7295 | const char *startSpecifier, unsigned specifierLen); |
7296 | bool checkForCStrMembers(const analyze_printf::ArgType &AT, |
7297 | const Expr *E); |
7298 | |
7299 | void HandleEmptyObjCModifierFlag(const char *startFlag, |
7300 | unsigned flagLen) override; |
7301 | |
7302 | void HandleInvalidObjCModifierFlag(const char *startFlag, |
7303 | unsigned flagLen) override; |
7304 | |
7305 | void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart, |
7306 | const char *flagsEnd, |
7307 | const char *conversionPosition) |
7308 | override; |
7309 | }; |
7310 | |
7311 | } |
7312 | |
7313 | bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier( |
7314 | const analyze_printf::PrintfSpecifier &FS, |
7315 | const char *startSpecifier, |
7316 | unsigned specifierLen) { |
7317 | const analyze_printf::PrintfConversionSpecifier &CS = |
7318 | FS.getConversionSpecifier(); |
7319 | |
7320 | return HandleInvalidConversionSpecifier(FS.getArgIndex(), |
7321 | getLocationOfByte(CS.getStart()), |
7322 | startSpecifier, specifierLen, |
7323 | CS.getStart(), CS.getLength()); |
7324 | } |
7325 | |
7326 | void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) { |
7327 | S.Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size); |
7328 | } |
7329 | |
7330 | bool CheckPrintfHandler::HandleAmount( |
7331 | const analyze_format_string::OptionalAmount &Amt, |
7332 | unsigned k, const char *startSpecifier, |
7333 | unsigned specifierLen) { |
7334 | if (Amt.hasDataArgument()) { |
7335 | if (!HasVAListArg) { |
7336 | unsigned argIndex = Amt.getArgIndex(); |
7337 | if (argIndex >= NumDataArgs) { |
7338 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_asterisk_missing_arg) |
7339 | << k, |
7340 | getLocationOfByte(Amt.getStart()), |
7341 | , |
7342 | getSpecifierRange(startSpecifier, specifierLen)); |
7343 | |
7344 | |
7345 | return false; |
7346 | } |
7347 | |
7348 | |
7349 | |
7350 | |
7351 | |
7352 | CoveredArgs.set(argIndex); |
7353 | const Expr *Arg = getDataArg(argIndex); |
7354 | if (!Arg) |
7355 | return false; |
7356 | |
7357 | QualType T = Arg->getType(); |
7358 | |
7359 | const analyze_printf::ArgType &AT = Amt.getArgType(S.Context); |
7360 | assert(AT.isValid()); |
7361 | |
7362 | if (!AT.matchesType(S.Context, T)) { |
7363 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_asterisk_wrong_type) |
7364 | << k << AT.getRepresentativeTypeName(S.Context) |
7365 | << T << Arg->getSourceRange(), |
7366 | getLocationOfByte(Amt.getStart()), |
7367 | , |
7368 | getSpecifierRange(startSpecifier, specifierLen)); |
7369 | |
7370 | |
7371 | return false; |
7372 | } |
7373 | } |
7374 | } |
7375 | return true; |
7376 | } |
7377 | |
7378 | void CheckPrintfHandler::HandleInvalidAmount( |
7379 | const analyze_printf::PrintfSpecifier &FS, |
7380 | const analyze_printf::OptionalAmount &Amt, |
7381 | unsigned type, |
7382 | const char *startSpecifier, |
7383 | unsigned specifierLen) { |
7384 | const analyze_printf::PrintfConversionSpecifier &CS = |
7385 | FS.getConversionSpecifier(); |
7386 | |
7387 | FixItHint fixit = |
7388 | Amt.getHowSpecified() == analyze_printf::OptionalAmount::Constant |
7389 | ? FixItHint::CreateRemoval(getSpecifierRange(Amt.getStart(), |
7390 | Amt.getConstantLength())) |
7391 | : FixItHint(); |
7392 | |
7393 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_nonsensical_optional_amount) |
7394 | << type << CS.toString(), |
7395 | getLocationOfByte(Amt.getStart()), |
7396 | , |
7397 | getSpecifierRange(startSpecifier, specifierLen), |
7398 | fixit); |
7399 | } |
7400 | |
7401 | void CheckPrintfHandler::HandleFlag(const analyze_printf::PrintfSpecifier &FS, |
7402 | const analyze_printf::OptionalFlag &flag, |
7403 | const char *startSpecifier, |
7404 | unsigned specifierLen) { |
7405 | |
7406 | const analyze_printf::PrintfConversionSpecifier &CS = |
7407 | FS.getConversionSpecifier(); |
7408 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_nonsensical_flag) |
7409 | << flag.toString() << CS.toString(), |
7410 | getLocationOfByte(flag.getPosition()), |
7411 | , |
7412 | getSpecifierRange(startSpecifier, specifierLen), |
7413 | FixItHint::CreateRemoval( |
7414 | getSpecifierRange(flag.getPosition(), 1))); |
7415 | } |
7416 | |
7417 | void CheckPrintfHandler::HandleIgnoredFlag( |
7418 | const analyze_printf::PrintfSpecifier &FS, |
7419 | const analyze_printf::OptionalFlag &ignoredFlag, |
7420 | const analyze_printf::OptionalFlag &flag, |
7421 | const char *startSpecifier, |
7422 | unsigned specifierLen) { |
7423 | |
7424 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_ignored_flag) |
7425 | << ignoredFlag.toString() << flag.toString(), |
7426 | getLocationOfByte(ignoredFlag.getPosition()), |
7427 | , |
7428 | getSpecifierRange(startSpecifier, specifierLen), |
7429 | FixItHint::CreateRemoval( |
7430 | getSpecifierRange(ignoredFlag.getPosition(), 1))); |
7431 | } |
7432 | |
7433 | void CheckPrintfHandler::HandleEmptyObjCModifierFlag(const char *startFlag, |
7434 | unsigned flagLen) { |
7435 | |
7436 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_empty_objc_flag), |
7437 | getLocationOfByte(startFlag), |
7438 | , |
7439 | getSpecifierRange(startFlag, flagLen)); |
7440 | } |
7441 | |
7442 | void CheckPrintfHandler::HandleInvalidObjCModifierFlag(const char *startFlag, |
7443 | unsigned flagLen) { |
7444 | |
7445 | auto Range = getSpecifierRange(startFlag, flagLen); |
7446 | StringRef flag(startFlag, flagLen); |
7447 | EmitFormatDiagnostic(S.PDiag(diag::warn_printf_invalid_objc_flag) << flag, |
7448 | getLocationOfByte(startFlag), |
7449 | , |
7450 | Range, FixItHint::CreateRemoval(Range)); |
7451 | } |
7452 | |
7453 | void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion( |
7454 | const char *flagsStart, const char *flagsEnd, const char *conversionPosition) { |
7455 | |
7456 | auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1); |
7457 | auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion; |
7458 | EmitFormatDiagnostic(S.PDiag(diag) << StringRef(conversionPosition, 1), |
7459 | getLocationOfByte(conversionPosition), |
7460 | , |
7461 | Range, FixItHint::CreateRemoval(Range)); |
7462 | } |
7463 | |
7464 | |
7465 | |
7466 | |
7467 | template<typename MemberKind> |
7468 | static llvm::SmallPtrSet<MemberKind*, 1> |
7469 | CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty) { |
7470 | const RecordType *RT = Ty->getAs<RecordType>(); |
7471 | llvm::SmallPtrSet<MemberKind*, 1> Results; |
7472 | |
7473 | if (!RT) |
7474 | return Results; |
7475 | const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); |
7476 | if (!RD || !RD->getDefinition()) |
7477 | return Results; |
7478 | |
7479 | LookupResult R(S, &S.Context.Idents.get(Name), SourceLocation(), |
7480 | Sema::LookupMemberName); |
7481 | R.suppressDiagnostics(); |
7482 | |
7483 | |
7484 | |
7485 | if (S.LookupQualifiedName(R, RT->getDecl())) |
7486 | for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { |
7487 | NamedDecl *decl = (*I)->getUnderlyingDecl(); |
7488 | if (MemberKind *FK = dyn_cast<MemberKind>(decl)) |
7489 | Results.insert(FK); |
7490 | } |
7491 | return Results; |
7492 | } |
7493 | |
7494 | |
7495 | |
7496 | |
7497 | |
7498 | bool Sema::hasCStrMethod(const Expr *E) { |
7499 | using MethodSet = llvm::SmallPtrSet<CXXMethodDecl *, 1>; |
7500 | |
7501 | MethodSet Results = |
7502 | CXXRecordMembersNamed<CXXMethodDecl>("c_str", *this, E->getType()); |
7503 | for (MethodSet::iterator MI = Results.begin(), ME = Results.end(); |
7504 | MI != ME; ++MI) |
7505 | if ((*MI)->getMinRequiredArguments() == 0) |
7506 | return true; |
7507 | return false; |
7508 | } |
7509 | |
7510 | |
7511 | |
7512 | |
7513 | bool CheckPrintfHandler::checkForCStrMembers( |
7514 | const analyze_printf::ArgType &AT, const Expr *E) { |
7515 | using MethodSet = llvm::SmallPtrSet<CXXMethodDecl *, 1>; |
7516 | |
7517 | MethodSet Results = |
7518 | CXXRecordMembersNamed<CXXMethodDecl>("c_str", S, E->getType()); |
7519 | |
7520 | for (MethodSet::iterator MI = Results.begin(), ME = Results.end(); |
7521 | MI != ME; ++MI) { |
7522 | const CXXMethodDecl *Method = *MI; |
7523 | if (Method->getMinRequiredArguments() == 0 && |
7524 | AT.matchesType(S.Context, Method->getReturnType())) { |
7525 | |
7526 | SourceLocation EndLoc = S.getLocForEndOfToken(E->getEndLoc()); |
7527 | S.Diag(E->getBeginLoc(), diag::note_printf_c_str) |
7528 | << "c_str()" << FixItHint::CreateInsertion(EndLoc, ".c_str()"); |
7529 | return true; |
7530 | } |
7531 | } |
7532 | |
7533 | return false; |
7534 | } |
7535 | |
7536 | bool |
7537 | CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier |
7538 | &FS, |
7539 | const char *startSpecifier, |
7540 | unsigned specifierLen) { |
7541 | using namespace analyze_format_string; |
7542 | using namespace analyze_printf; |
7543 | |
7544 | const PrintfConversionSpecifier &CS = FS.getConversionSpecifier(); |
7545 | |
7546 | if (FS.consumesDataArgument()) { |
7547 | if (atFirstArg) { |
7548 | atFirstArg = false; |
7549 | usesPositionalArgs = FS.usesPositionalArg(); |
7550 | } |
7551 | else if (usesPositionalArgs != FS.usesPositionalArg()) { |
7552 | HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()), |
7553 | startSpecifier, specifierLen); |
7554 | return false; |
7555 | } |
7556 | } |
7557 | |
7558 | |
7559 | |
7560 | if (!HandleAmount(FS.getFieldWidth(), 0, |
7561 | startSpecifier, specifierLen)) { |
7562 | return false; |
7563 | } |
7564 | |
7565 | if (!HandleAmount(FS.getPrecision(), 1, |
7566 | startSpecifier, specifierLen)) { |
7567 | return false; |
7568 | } |
7569 | |
7570 | if (!CS.consumesDataArgument()) { |
7571 | |
7572 | |
7573 | return true; |
7574 | } |
7575 | |
7576 | |
7577 | unsigned argIndex = FS.getArgIndex(); |
7578 | if (argIndex < NumDataArgs) { |
7579 | |
7580 | |
7581 | |
7582 | CoveredArgs.set(argIndex); |
7583 | } |
7584 | |
7585 | |
7586 | if (CS.getKind() == ConversionSpecifier::FreeBSDbArg || |
7587 | CS.getKind() == ConversionSpecifier::FreeBSDDArg) { |
7588 | |
7589 | if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1)) |
7590 | return false; |
7591 | |
7592 | |
7593 | CoveredArgs.set(argIndex + 1); |
7594 | |
7595 | |
7596 | const Expr *Ex = getDataArg(argIndex); |
7597 | const analyze_printf::ArgType &AT = |
7598 | (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ? |
7599 | ArgType(S.Context.IntTy) : ArgType::CPointerTy; |
7600 | if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) |
7601 | EmitFormatDiagnostic( |
7602 | S.PDiag(diag::warn_format_conversion_argument_type_mismatch) |
7603 | << AT.getRepresentativeTypeName(S.Context) << Ex->getType() |
7604 | << false << Ex->getSourceRange(), |
7605 | Ex->getBeginLoc(), false, |
7606 | getSpecifierRange(startSpecifier, specifierLen)); |
7607 | |
7608 | |
7609 | Ex = getDataArg(argIndex + 1); |
7610 | const analyze_printf::ArgType &AT2 = ArgType::CStrTy; |
7611 | if (AT2.isValid() && !AT2.matchesType(S.Context, Ex->getType())) |
7612 | EmitFormatDiagnostic( |
7613 | S.PDiag(diag::warn_format_conversion_argument_type_mismatch) |
7614 | << AT2.getRepresentativeTypeName(S.Context) << Ex->getType() |
7615 | << false << Ex->getSourceRange(), |
7616 | Ex->getBeginLoc(), false, |
7617 | getSpecifierRange(startSpecifier, specifierLen)); |
7618 | |
7619 | return true; |
7620 | } |
7621 | |
7622 | |
7623 | |
7624 | if (!allowsObjCArg() && CS.isObjCArg()) { |
7625 | return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, |
7626 | specifierLen); |
7627 | } |
7628 | |
7629 | |
7630 | if (FSType != Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) { |
7631 | return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, |
7632 | specifierLen); |
7633 | } |
7634 | |
7635 | |
7636 | if (FSType == Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) { |
7637 | EmitFormatDiagnostic(S.PDiag(diag::warn_os_log_format_narg), |
7638 | getLocationOfByte(CS.getStart()), |
7639 | false, |
7640 | getSpecifierRange(startSpecifier, specifierLen)); |
7641 | |
7642 | return true; |
7643 | } |
7644 | |
7645 | |
7646 | if (FSType == Sema::FST_OSTrace && |
7647 | (CS.getKind() == ConversionSpecifier::PArg || |
7648 | CS.getKind() == ConversionSpecifier::sArg || |
7649 | CS.getKind() == ConversionSpecifier::ObjCObjArg)) { |
7650 | return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, |
7651 | specifierLen); |
7652 | } |
7653 | |
7654 | |
7655 | if (FSType != Sema::FST_OSLog) { |
7656 | if (FS.isPublic().isSet()) { |
7657 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_invalid_annotation) |
7658 | << "public", |
7659 | getLocationOfByte(FS.isPublic().getPosition()), |
7660 | false, |
7661 | getSpecifierRange(startSpecifier, specifierLen)); |
7662 | } |
7663 | if (FS.isPrivate().isSet()) { |
7664 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_invalid_annotation) |
7665 | << "private", |
7666 | getLocationOfByte(FS.isPrivate().getPosition()), |
7667 | false, |
7668 | getSpecifierRange(startSpecifier, specifierLen)); |
7669 | } |
7670 | } |
7671 | |
7672 | |
7673 | if (!FS.hasValidFieldWidth()) { |
7674 | HandleInvalidAmount(FS, FS.getFieldWidth(), 0, |
7675 | startSpecifier, specifierLen); |
7676 | } |
7677 | |
7678 | |
7679 | if (!FS.hasValidPrecision()) { |
7680 | HandleInvalidAmount(FS, FS.getPrecision(), 1, |
7681 | startSpecifier, specifierLen); |
7682 | } |
7683 | |
7684 | |
7685 | if (CS.getKind() == ConversionSpecifier::PArg && |
7686 | FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) { |
7687 | EmitFormatDiagnostic(S.PDiag(diag::warn_format_P_no_precision), |
7688 | getLocationOfByte(startSpecifier), |
7689 | false, |
7690 | getSpecifierRange(startSpecifier, specifierLen)); |
7691 | } |
7692 | |
7693 | |
7694 | if (!FS.hasValidThousandsGroupingPrefix()) |
7695 | HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen); |
7696 | if (!FS.hasValidLeadingZeros()) |
7697 | HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen); |
7698 | if (!FS.hasValidPlusPrefix()) |
7699 | HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen); |
7700 | if (!FS.hasValidSpacePrefix()) |
7701 | HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen); |
7702 | if (!FS.hasValidAlternativeForm()) |
7703 | HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen); |
7704 | if (!FS.hasValidLeftJustified()) |
7705 | HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen); |
7706 | |
7707 | |
7708 | if (FS.hasSpacePrefix() && FS.hasPlusPrefix()) |
7709 | HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(), |
7710 | startSpecifier, specifierLen); |
7711 | if (FS.hasLeadingZeros() && FS.isLeftJustified()) |
7712 | HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(), |
7713 | startSpecifier, specifierLen); |
7714 | |
7715 | |
7716 | if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(), |
7717 | S.getLangOpts())) |
7718 | HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen, |
7719 | diag::warn_format_nonsensical_length); |
7720 | else if (!FS.hasStandardLengthModifier()) |
7721 | HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen); |
7722 | else if (!FS.hasStandardLengthConversionCombination()) |
7723 | HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen, |
7724 | diag::warn_format_non_standard_conversion_spec); |
7725 | |
7726 | if (!FS.hasStandardConversionSpecifier(S.getLangOpts())) |
7727 | HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen); |
7728 | |
7729 | |
7730 | if (HasVAListArg) |
7731 | return true; |
7732 | |
7733 | if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex)) |
7734 | return false; |
7735 | |
7736 | const Expr *Arg = getDataArg(argIndex); |
7737 | if (!Arg) |
7738 | return true; |
7739 | |
7740 | return checkFormatExpr(FS, startSpecifier, specifierLen, Arg); |
7741 | } |
7742 | |
7743 | static bool requiresParensToAddCast(const Expr *E) { |
7744 | |
7745 | |
7746 | |
7747 | const Expr *Inside = E->IgnoreImpCasts(); |
7748 | if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(Inside)) |
7749 | Inside = POE->getSyntacticForm()->IgnoreImpCasts(); |
7750 | |
7751 | switch (Inside->getStmtClass()) { |
7752 | case Stmt::ArraySubscriptExprClass: |
7753 | case Stmt::CallExprClass: |
7754 | case Stmt::CharacterLiteralClass: |
7755 | case Stmt::CXXBoolLiteralExprClass: |
7756 | case Stmt::DeclRefExprClass: |
7757 | case Stmt::FloatingLiteralClass: |
7758 | case Stmt::IntegerLiteralClass: |
7759 | case Stmt::MemberExprClass: |
7760 | case Stmt::ObjCArrayLiteralClass: |
7761 | case Stmt::ObjCBoolLiteralExprClass: |
7762 | case Stmt::ObjCBoxedExprClass: |
7763 | case Stmt::ObjCDictionaryLiteralClass: |
7764 | case Stmt::ObjCEncodeExprClass: |
7765 | case Stmt::ObjCIvarRefExprClass: |
7766 | case Stmt::ObjCMessageExprClass: |
7767 | case Stmt::ObjCPropertyRefExprClass: |
7768 | case Stmt::ObjCStringLiteralClass: |
7769 | case Stmt::ObjCSubscriptRefExprClass: |
7770 | case Stmt::ParenExprClass: |
7771 | case Stmt::StringLiteralClass: |
7772 | case Stmt::UnaryOperatorClass: |
7773 | return false; |
7774 | default: |
7775 | return true; |
7776 | } |
7777 | } |
7778 | |
7779 | static std::pair<QualType, StringRef> |
7780 | shouldNotPrintDirectly(const ASTContext &Context, |
7781 | QualType IntendedTy, |
7782 | const Expr *E) { |
7783 | |
7784 | QualType TyTy = IntendedTy; |
7785 | while (const TypedefType *UserTy = TyTy->getAs<TypedefType>()) { |
7786 | StringRef Name = UserTy->getDecl()->getName(); |
7787 | QualType CastTy = llvm::StringSwitch<QualType>(Name) |
7788 | .Case("CFIndex", Context.getNSIntegerType()) |
7789 | .Case("NSInteger", Context.getNSIntegerType()) |
7790 | .Case("NSUInteger", Context.getNSUIntegerType()) |
7791 | .Case("SInt32", Context.IntTy) |
7792 | .Case("UInt32", Context.UnsignedIntTy) |
7793 | .Default(QualType()); |
7794 | |
7795 | if (!CastTy.isNull()) |
7796 | return std::make_pair(CastTy, Name); |
7797 | |
7798 | TyTy = UserTy->desugar(); |
7799 | } |
7800 | |
7801 | |
7802 | if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) |
7803 | return shouldNotPrintDirectly(Context, |
7804 | PE->getSubExpr()->getType(), |
7805 | PE->getSubExpr()); |
7806 | |
7807 | |
7808 | |
7809 | |
7810 | |
7811 | if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { |
7812 | QualType TrueTy, FalseTy; |
7813 | StringRef TrueName, FalseName; |
7814 | |
7815 | std::tie(TrueTy, TrueName) = |
7816 | shouldNotPrintDirectly(Context, |
7817 | CO->getTrueExpr()->getType(), |
7818 | CO->getTrueExpr()); |
7819 | std::tie(FalseTy, FalseName) = |
7820 | shouldNotPrintDirectly(Context, |
7821 | CO->getFalseExpr()->getType(), |
7822 | CO->getFalseExpr()); |
7823 | |
7824 | if (TrueTy == FalseTy) |
7825 | return std::make_pair(TrueTy, TrueName); |
7826 | else if (TrueTy.isNull()) |
7827 | return std::make_pair(FalseTy, FalseName); |
7828 | else if (FalseTy.isNull()) |
7829 | return std::make_pair(TrueTy, TrueName); |
7830 | } |
7831 | |
7832 | return std::make_pair(QualType(), StringRef()); |
7833 | } |
7834 | |
7835 | |
7836 | |
7837 | |
7838 | static bool |
7839 | isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE) { |
7840 | QualType From = ICE->getSubExpr()->getType(); |
7841 | QualType To = ICE->getType(); |
7842 | |
7843 | |
7844 | if (ICE->getCastKind() == CK_IntegralCast && |
7845 | From->isPromotableIntegerType() && |
7846 | S.Context.getPromotedIntegerType(From) == To) |
7847 | return true; |
7848 | |
7849 | |
7850 | if (const auto *VecTy = From->getAs<ExtVectorType>()) |
7851 | From = VecTy->getElementType(); |
7852 | if (const auto *VecTy = To->getAs<ExtVectorType>()) |
7853 | To = VecTy->getElementType(); |
7854 | |
7855 | return ICE->getCastKind() == CK_FloatingCast && |
7856 | S.Context.getFloatingTypeOrder(From, To) < 0; |
7857 | } |
7858 | |
7859 | bool |
7860 | CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, |
7861 | const char *StartSpecifier, |
7862 | unsigned SpecifierLen, |
7863 | const Expr *E) { |
7864 | using namespace analyze_format_string; |
7865 | using namespace analyze_printf; |
7866 | |
7867 | |
7868 | |
7869 | const analyze_printf::ArgType &AT = FS.getArgType(S.Context, isObjCContext()); |
7870 | if (!AT.isValid()) |
7871 | return true; |
7872 | |
7873 | QualType ExprTy = E->getType(); |
7874 | while (const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) { |
7875 | ExprTy = TET->getUnderlyingExpr()->getType(); |
7876 | } |
7877 | |
7878 | const analyze_printf::ArgType::MatchKind Match = |
7879 | AT.matchesType(S.Context, ExprTy); |
7880 | bool Pedantic = Match == analyze_printf::ArgType::NoMatchPedantic; |
7881 | if (Match == analyze_printf::ArgType::Match) |
7882 | return true; |
7883 | |
7884 | |
7885 | |
7886 | |
7887 | |
7888 | |
7889 | if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { |
7890 | if (isArithmeticArgumentPromotion(S, ICE)) { |
7891 | E = ICE->getSubExpr(); |
7892 | ExprTy = E->getType(); |
7893 | |
7894 | |
7895 | |
7896 | |
7897 | if (ICE->getType() == S.Context.IntTy || |
7898 | ICE->getType() == S.Context.UnsignedIntTy) { |
7899 | |
7900 | if (AT.matchesType(S.Context, ExprTy)) |
7901 | return true; |
7902 | } |
7903 | } |
7904 | } else if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) { |
7905 | |
7906 | |
7907 | |
7908 | if (ExprTy == S.Context.IntTy) |
7909 | if (llvm::isUIntN(S.Context.getCharWidth(), CL->getValue())) |
7910 | ExprTy = S.Context.CharTy; |
7911 | } |
7912 | |
7913 | |
7914 | bool IsEnum = false; |
7915 | if (auto EnumTy = ExprTy->getAs<EnumType>()) { |
7916 | ExprTy = EnumTy->getDecl()->getIntegerType(); |
7917 | IsEnum = true; |
7918 | } |
7919 | |
7920 | |
7921 | |
7922 | |
7923 | QualType IntendedTy = ExprTy; |
7924 | if (isObjCContext() && |
7925 | FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) { |
7926 | if (ExprTy->isIntegralOrUnscopedEnumerationType() && |
7927 | !ExprTy->isCharType()) { |
7928 | |
7929 | |
7930 | IntendedTy = S.Context.UnsignedShortTy; |
7931 | |
7932 | |
7933 | |
7934 | if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) { |
7935 | const llvm::APInt &V = IL->getValue(); |
7936 | if (V.getActiveBits() <= S.Context.getTypeSize(IntendedTy)) |
7937 | return true; |
7938 | } |
7939 | |
7940 | LookupResult Result(S, &S.Context.Idents.get("unichar"), E->getBeginLoc(), |
7941 | Sema::LookupOrdinaryName); |
7942 | if (S.LookupName(Result, S.getCurScope())) { |
7943 | NamedDecl *ND = Result.getFoundDecl(); |
7944 | if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(ND)) |
7945 | if (TD->getUnderlyingType() == IntendedTy) |
7946 | IntendedTy = S.Context.getTypedefType(TD); |
7947 | } |
7948 | } |
7949 | } |
7950 | |
7951 | |
7952 | |
7953 | bool ShouldNotPrintDirectly = false; StringRef CastTyName; |
7954 | if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { |
7955 | QualType CastTy; |
7956 | std::tie(CastTy, CastTyName) = shouldNotPrintDirectly(S.Context, IntendedTy, E); |
7957 | if (!CastTy.isNull()) { |
7958 | |
7959 | |
7960 | if ((CastTyName == "NSInteger" || CastTyName == "NSUInteger") && |
7961 | (AT.isSizeT() || AT.isPtrdiffT()) && |
7962 | AT.matchesType(S.Context, CastTy)) |
7963 | Pedantic = true; |
7964 | IntendedTy = CastTy; |
7965 | ShouldNotPrintDirectly = true; |
7966 | } |
7967 | } |
7968 | |
7969 | |
7970 | PrintfSpecifier fixedFS = FS; |
7971 | bool Success = |
7972 | fixedFS.fixType(IntendedTy, S.getLangOpts(), S.Context, isObjCContext()); |
7973 | |
7974 | if (Success) { |
7975 | |
7976 | SmallString<16> buf; |
7977 | llvm::raw_svector_ostream os(buf); |
7978 | fixedFS.toString(os); |
7979 | |
7980 | CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen); |
7981 | |
7982 | if (IntendedTy == ExprTy && !ShouldNotPrintDirectly) { |
7983 | unsigned Diag = |
7984 | Pedantic |
7985 | ? diag::warn_format_conversion_argument_type_mismatch_pedantic |
7986 | : diag::warn_format_conversion_argument_type_mismatch; |
7987 | |
7988 | |
7989 | EmitFormatDiagnostic(S.PDiag(Diag) |
7990 | << AT.getRepresentativeTypeName(S.Context) |
7991 | << IntendedTy << IsEnum << E->getSourceRange(), |
7992 | E->getBeginLoc(), |
7993 | false, SpecRange, |
7994 | FixItHint::CreateReplacement(SpecRange, os.str())); |
7995 | } else { |
7996 | |
7997 | |
7998 | |
7999 | |
8000 | |
8001 | |
8002 | |
8003 | SmallString<16> CastBuf; |
8004 | llvm::raw_svector_ostream CastFix(CastBuf); |
8005 | CastFix << "("; |
8006 | IntendedTy.print(CastFix, S.Context.getPrintingPolicy()); |
8007 | CastFix << ")"; |
8008 | |
8009 | SmallVector<FixItHint,4> Hints; |
8010 | if (!AT.matchesType(S.Context, IntendedTy) || ShouldNotPrintDirectly) |
8011 | Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str())); |
8012 | |
8013 | if (const CStyleCastExpr *CCast = dyn_cast<CStyleCastExpr>(E)) { |
8014 | |
8015 | SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc()); |
8016 | Hints.push_back(FixItHint::CreateReplacement(CastRange, CastFix.str())); |
8017 | |
8018 | } else if (!requiresParensToAddCast(E)) { |
8019 | |
8020 | |
8021 | Hints.push_back( |
8022 | FixItHint::CreateInsertion(E->getBeginLoc(), CastFix.str())); |
8023 | } else { |
8024 | |
8025 | CastFix << "("; |
8026 | Hints.push_back( |
8027 | FixItHint::CreateInsertion(E->getBeginLoc(), CastFix.str())); |
8028 | |
8029 | SourceLocation After = S.getLocForEndOfToken(E->getEndLoc()); |
8030 | Hints.push_back(FixItHint::CreateInsertion(After, ")")); |
8031 | } |
8032 | |
8033 | if (ShouldNotPrintDirectly) { |
8034 | |
8035 | |
8036 | |
8037 | StringRef Name; |
8038 | if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(ExprTy)) |
8039 | Name = TypedefTy->getDecl()->getName(); |
8040 | else |
8041 | Name = CastTyName; |
8042 | unsigned Diag = Pedantic |
8043 | ? diag::warn_format_argument_needs_cast_pedantic |
8044 | : diag::warn_format_argument_needs_cast; |
8045 | EmitFormatDiagnostic(S.PDiag(Diag) << Name << IntendedTy << IsEnum |
8046 | << E->getSourceRange(), |
8047 | E->getBeginLoc(), , |
8048 | SpecRange, Hints); |
8049 | } else { |
8050 | |
8051 | |
8052 | |
8053 | EmitFormatDiagnostic( |
8054 | S.PDiag(diag::warn_format_conversion_argument_type_mismatch) |
8055 | << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum |
8056 | << E->getSourceRange(), |
8057 | E->getBeginLoc(), false, SpecRange, Hints); |
8058 | } |
8059 | } |
8060 | } else { |
8061 | const CharSourceRange &CSR = getSpecifierRange(StartSpecifier, |
8062 | SpecifierLen); |
8063 | |
8064 | |
8065 | |
8066 | switch (S.isValidVarArgType(ExprTy)) { |
8067 | case Sema::VAK_Valid: |
8068 | case Sema::VAK_ValidInCXX11: { |
8069 | unsigned Diag = |
8070 | Pedantic |
8071 | ? diag::warn_format_conversion_argument_type_mismatch_pedantic |
8072 | : diag::warn_format_conversion_argument_type_mismatch; |
8073 | |
8074 | EmitFormatDiagnostic( |
8075 | S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy |
8076 | << IsEnum << CSR << E->getSourceRange(), |
8077 | E->getBeginLoc(), false, CSR); |
8078 | break; |
8079 | } |
8080 | case Sema::VAK_Undefined: |
8081 | case Sema::VAK_MSVCUndefined: |
8082 | EmitFormatDiagnostic(S.PDiag(diag::warn_non_pod_vararg_with_format_string) |
8083 | << S.getLangOpts().CPlusPlus11 << ExprTy |
8084 | << CallType |
8085 | << AT.getRepresentativeTypeName(S.Context) << CSR |
8086 | << E->getSourceRange(), |
8087 | E->getBeginLoc(), false, CSR); |
8088 | checkForCStrMembers(AT, E); |
8089 | break; |
8090 | |
8091 | case Sema::VAK_Invalid: |
8092 | if (ExprTy->isObjCObjectType()) |
8093 | EmitFormatDiagnostic( |
8094 | S.PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format) |
8095 | << S.getLangOpts().CPlusPlus11 << ExprTy << CallType |
8096 | << AT.getRepresentativeTypeName(S.Context) << CSR |
8097 | << E->getSourceRange(), |
8098 | E->getBeginLoc(), false, CSR); |
8099 | else |
8100 | |
8101 | |
8102 | S.Diag(E->getBeginLoc(), diag::err_cannot_pass_to_vararg_format) |
8103 | << isa<InitListExpr>(E) << ExprTy << CallType |
8104 | << AT.getRepresentativeTypeName(S.Context) << E->getSourceRange(); |
8105 | break; |
8106 | } |
8107 | |
8108 | (0) . __assert_fail ("FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() && \"format string specifier index out of range\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 8109, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() && |
8109 | (0) . __assert_fail ("FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() && \"format string specifier index out of range\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 8109, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "format string specifier index out of range"); |
8110 | CheckedVarArgs[FirstDataArg + FS.getArgIndex()] = true; |
8111 | } |
8112 | |
8113 | return true; |
8114 | } |
8115 | |
8116 | |
8117 | |
8118 | namespace { |
8119 | |
8120 | class CheckScanfHandler : public CheckFormatHandler { |
8121 | public: |
8122 | CheckScanfHandler(Sema &s, const FormatStringLiteral *fexpr, |
8123 | const Expr *origFormatExpr, Sema::FormatStringType type, |
8124 | unsigned firstDataArg, unsigned numDataArgs, |
8125 | const char *beg, bool hasVAListArg, |
8126 | ArrayRef<const Expr *> Args, unsigned formatIdx, |
8127 | bool inFunctionCall, Sema::VariadicCallType CallType, |
8128 | llvm::SmallBitVector &CheckedVarArgs, |
8129 | UncoveredArgHandler &UncoveredArg) |
8130 | : CheckFormatHandler(s, fexpr, origFormatExpr, type, firstDataArg, |
8131 | numDataArgs, beg, hasVAListArg, Args, formatIdx, |
8132 | inFunctionCall, CallType, CheckedVarArgs, |
8133 | UncoveredArg) {} |
8134 | |
8135 | bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, |
8136 | const char *startSpecifier, |
8137 | unsigned specifierLen) override; |
8138 | |
8139 | bool HandleInvalidScanfConversionSpecifier( |
8140 | const analyze_scanf::ScanfSpecifier &FS, |
8141 | const char *startSpecifier, |
8142 | unsigned specifierLen) override; |
8143 | |
8144 | void HandleIncompleteScanList(const char *start, const char *end) override; |
8145 | }; |
8146 | |
8147 | } |
8148 | |
8149 | void CheckScanfHandler::HandleIncompleteScanList(const char *start, |
8150 | const char *end) { |
8151 | EmitFormatDiagnostic(S.PDiag(diag::warn_scanf_scanlist_incomplete), |
8152 | getLocationOfByte(end), , |
8153 | getSpecifierRange(start, end - start)); |
8154 | } |
8155 | |
8156 | bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier( |
8157 | const analyze_scanf::ScanfSpecifier &FS, |
8158 | const char *startSpecifier, |
8159 | unsigned specifierLen) { |
8160 | const analyze_scanf::ScanfConversionSpecifier &CS = |
8161 | FS.getConversionSpecifier(); |
8162 | |
8163 | return HandleInvalidConversionSpecifier(FS.getArgIndex(), |
8164 | getLocationOfByte(CS.getStart()), |
8165 | startSpecifier, specifierLen, |
8166 | CS.getStart(), CS.getLength()); |
8167 | } |
8168 | |
8169 | bool CheckScanfHandler::HandleScanfSpecifier( |
8170 | const analyze_scanf::ScanfSpecifier &FS, |
8171 | const char *startSpecifier, |
8172 | unsigned specifierLen) { |
8173 | using namespace analyze_scanf; |
8174 | using namespace analyze_format_string; |
8175 | |
8176 | const ScanfConversionSpecifier &CS = FS.getConversionSpecifier(); |
8177 | |
8178 | |
8179 | |
8180 | if (FS.consumesDataArgument()) { |
8181 | if (atFirstArg) { |
8182 | atFirstArg = false; |
8183 | usesPositionalArgs = FS.usesPositionalArg(); |
8184 | } |
8185 | else if (usesPositionalArgs != FS.usesPositionalArg()) { |
8186 | HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()), |
8187 | startSpecifier, specifierLen); |
8188 | return false; |
8189 | } |
8190 | } |
8191 | |
8192 | |
8193 | const OptionalAmount &Amt = FS.getFieldWidth(); |
8194 | if (Amt.getHowSpecified() == OptionalAmount::Constant) { |
8195 | if (Amt.getConstantAmount() == 0) { |
8196 | const CharSourceRange &R = getSpecifierRange(Amt.getStart(), |
8197 | Amt.getConstantLength()); |
8198 | EmitFormatDiagnostic(S.PDiag(diag::warn_scanf_nonzero_width), |
8199 | getLocationOfByte(Amt.getStart()), |
8200 | , R, |
8201 | FixItHint::CreateRemoval(R)); |
8202 | } |
8203 | } |
8204 | |
8205 | if (!FS.consumesDataArgument()) { |
8206 | |
8207 | |
8208 | return true; |
8209 | } |
8210 | |
8211 | |
8212 | unsigned argIndex = FS.getArgIndex(); |
8213 | if (argIndex < NumDataArgs) { |
8214 | |
8215 | |
8216 | |
8217 | CoveredArgs.set(argIndex); |
8218 | } |
8219 | |
8220 | |
8221 | if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(), |
8222 | S.getLangOpts())) |
8223 | HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen, |
8224 | diag::warn_format_nonsensical_length); |
8225 | else if (!FS.hasStandardLengthModifier()) |
8226 | HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen); |
8227 | else if (!FS.hasStandardLengthConversionCombination()) |
8228 | HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen, |
8229 | diag::warn_format_non_standard_conversion_spec); |
8230 | |
8231 | if (!FS.hasStandardConversionSpecifier(S.getLangOpts())) |
8232 | HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen); |
8233 | |
8234 | |
8235 | if (HasVAListArg) |
8236 | return true; |
8237 | |
8238 | if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex)) |
8239 | return false; |
8240 | |
8241 | |
8242 | const Expr *Ex = getDataArg(argIndex); |
8243 | if (!Ex) |
8244 | return true; |
8245 | |
8246 | const analyze_format_string::ArgType &AT = FS.getArgType(S.Context); |
8247 | |
8248 | if (!AT.isValid()) { |
8249 | return true; |
8250 | } |
8251 | |
8252 | analyze_format_string::ArgType::MatchKind Match = |
8253 | AT.matchesType(S.Context, Ex->getType()); |
8254 | bool Pedantic = Match == analyze_format_string::ArgType::NoMatchPedantic; |
8255 | if (Match == analyze_format_string::ArgType::Match) |
8256 | return true; |
8257 | |
8258 | ScanfSpecifier fixedFS = FS; |
8259 | bool Success = fixedFS.fixType(Ex->getType(), Ex->IgnoreImpCasts()->getType(), |
8260 | S.getLangOpts(), S.Context); |
8261 | |
8262 | unsigned Diag = |
8263 | Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic |
8264 | : diag::warn_format_conversion_argument_type_mismatch; |
8265 | |
8266 | if (Success) { |
8267 | |
8268 | SmallString<128> buf; |
8269 | llvm::raw_svector_ostream os(buf); |
8270 | fixedFS.toString(os); |
8271 | |
8272 | EmitFormatDiagnostic( |
8273 | S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) |
8274 | << Ex->getType() << false << Ex->getSourceRange(), |
8275 | Ex->getBeginLoc(), |
8276 | false, |
8277 | getSpecifierRange(startSpecifier, specifierLen), |
8278 | FixItHint::CreateReplacement( |
8279 | getSpecifierRange(startSpecifier, specifierLen), os.str())); |
8280 | } else { |
8281 | EmitFormatDiagnostic(S.PDiag(Diag) |
8282 | << AT.getRepresentativeTypeName(S.Context) |
8283 | << Ex->getType() << false << Ex->getSourceRange(), |
8284 | Ex->getBeginLoc(), |
8285 | false, |
8286 | getSpecifierRange(startSpecifier, specifierLen)); |
8287 | } |
8288 | |
8289 | return true; |
8290 | } |
8291 | |
8292 | static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, |
8293 | const Expr *OrigFormatExpr, |
8294 | ArrayRef<const Expr *> Args, |
8295 | bool HasVAListArg, unsigned format_idx, |
8296 | unsigned firstDataArg, |
8297 | Sema::FormatStringType Type, |
8298 | bool inFunctionCall, |
8299 | Sema::VariadicCallType CallType, |
8300 | llvm::SmallBitVector &CheckedVarArgs, |
8301 | UncoveredArgHandler &UncoveredArg) { |
8302 | |
8303 | if (!FExpr->isAscii() && !FExpr->isUTF8()) { |
8304 | CheckFormatHandler::EmitFormatDiagnostic( |
8305 | S, inFunctionCall, Args[format_idx], |
8306 | S.PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(), |
8307 | true, OrigFormatExpr->getSourceRange()); |
8308 | return; |
8309 | } |
8310 | |
8311 | |
8312 | StringRef StrRef = FExpr->getString(); |
8313 | const char *Str = StrRef.data(); |
8314 | |
8315 | const ConstantArrayType *T = |
8316 | S.Context.getAsConstantArrayType(FExpr->getType()); |
8317 | (0) . __assert_fail ("T && \"String literal not of constant array type!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 8317, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(T && "String literal not of constant array type!"); |
8318 | size_t TypeSize = T->getSize().getZExtValue(); |
8319 | size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size()); |
8320 | const unsigned numDataArgs = Args.size() - firstDataArg; |
8321 | |
8322 | |
8323 | |
8324 | if (TypeSize <= StrRef.size() && |
8325 | StrRef.substr(0, TypeSize).find('\0') == StringRef::npos) { |
8326 | CheckFormatHandler::EmitFormatDiagnostic( |
8327 | S, inFunctionCall, Args[format_idx], |
8328 | S.PDiag(diag::warn_printf_format_string_not_null_terminated), |
8329 | FExpr->getBeginLoc(), |
8330 | , OrigFormatExpr->getSourceRange()); |
8331 | return; |
8332 | } |
8333 | |
8334 | |
8335 | if (StrLen == 0 && numDataArgs > 0) { |
8336 | CheckFormatHandler::EmitFormatDiagnostic( |
8337 | S, inFunctionCall, Args[format_idx], |
8338 | S.PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(), |
8339 | true, OrigFormatExpr->getSourceRange()); |
8340 | return; |
8341 | } |
8342 | |
8343 | if (Type == Sema::FST_Printf || Type == Sema::FST_NSString || |
8344 | Type == Sema::FST_FreeBSDKPrintf || Type == Sema::FST_OSLog || |
8345 | Type == Sema::FST_OSTrace) { |
8346 | CheckPrintfHandler H( |
8347 | S, FExpr, OrigFormatExpr, Type, firstDataArg, numDataArgs, |
8348 | (Type == Sema::FST_NSString || Type == Sema::FST_OSTrace), Str, |
8349 | HasVAListArg, Args, format_idx, inFunctionCall, CallType, |
8350 | CheckedVarArgs, UncoveredArg); |
8351 | |
8352 | if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen, |
8353 | S.getLangOpts(), |
8354 | S.Context.getTargetInfo(), |
8355 | Type == Sema::FST_FreeBSDKPrintf)) |
8356 | H.DoneProcessing(); |
8357 | } else if (Type == Sema::FST_Scanf) { |
8358 | CheckScanfHandler H(S, FExpr, OrigFormatExpr, Type, firstDataArg, |
8359 | numDataArgs, Str, HasVAListArg, Args, format_idx, |
8360 | inFunctionCall, CallType, CheckedVarArgs, UncoveredArg); |
8361 | |
8362 | if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen, |
8363 | S.getLangOpts(), |
8364 | S.Context.getTargetInfo())) |
8365 | H.DoneProcessing(); |
8366 | } |
8367 | } |
8368 | |
8369 | bool Sema::FormatStringHasSArg(const StringLiteral *FExpr) { |
8370 | |
8371 | StringRef StrRef = FExpr->getString(); |
8372 | const char *Str = StrRef.data(); |
8373 | |
8374 | const ConstantArrayType *T = Context.getAsConstantArrayType(FExpr->getType()); |
8375 | (0) . __assert_fail ("T && \"String literal not of constant array type!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 8375, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(T && "String literal not of constant array type!"); |
8376 | size_t TypeSize = T->getSize().getZExtValue(); |
8377 | size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size()); |
8378 | return analyze_format_string::ParseFormatStringHasSArg(Str, Str + StrLen, |
8379 | getLangOpts(), |
8380 | Context.getTargetInfo()); |
8381 | } |
8382 | |
8383 | |
8384 | |
8385 | |
8386 | |
8387 | static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction) { |
8388 | switch (AbsFunction) { |
8389 | default: |
8390 | return 0; |
8391 | |
8392 | case Builtin::BI__builtin_abs: |
8393 | return Builtin::BI__builtin_labs; |
8394 | case Builtin::BI__builtin_labs: |
8395 | return Builtin::BI__builtin_llabs; |
8396 | case Builtin::BI__builtin_llabs: |
8397 | return 0; |
8398 | |
8399 | case Builtin::BI__builtin_fabsf: |
8400 | return Builtin::BI__builtin_fabs; |
8401 | case Builtin::BI__builtin_fabs: |
8402 | return Builtin::BI__builtin_fabsl; |
8403 | case Builtin::BI__builtin_fabsl: |
8404 | return 0; |
8405 | |
8406 | case Builtin::BI__builtin_cabsf: |
8407 | return Builtin::BI__builtin_cabs; |
8408 | case Builtin::BI__builtin_cabs: |
8409 | return Builtin::BI__builtin_cabsl; |
8410 | case Builtin::BI__builtin_cabsl: |
8411 | return 0; |
8412 | |
8413 | case Builtin::BIabs: |
8414 | return Builtin::BIlabs; |
8415 | case Builtin::BIlabs: |
8416 | return Builtin::BIllabs; |
8417 | case Builtin::BIllabs: |
8418 | return 0; |
8419 | |
8420 | case Builtin::BIfabsf: |
8421 | return Builtin::BIfabs; |
8422 | case Builtin::BIfabs: |
8423 | return Builtin::BIfabsl; |
8424 | case Builtin::BIfabsl: |
8425 | return 0; |
8426 | |
8427 | case Builtin::BIcabsf: |
8428 | return Builtin::BIcabs; |
8429 | case Builtin::BIcabs: |
8430 | return Builtin::BIcabsl; |
8431 | case Builtin::BIcabsl: |
8432 | return 0; |
8433 | } |
8434 | } |
8435 | |
8436 | |
8437 | static QualType getAbsoluteValueArgumentType(ASTContext &Context, |
8438 | unsigned AbsType) { |
8439 | if (AbsType == 0) |
8440 | return QualType(); |
8441 | |
8442 | ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None; |
8443 | QualType BuiltinType = Context.GetBuiltinType(AbsType, Error); |
8444 | if (Error != ASTContext::GE_None) |
8445 | return QualType(); |
8446 | |
8447 | const FunctionProtoType *FT = BuiltinType->getAs<FunctionProtoType>(); |
8448 | if (!FT) |
8449 | return QualType(); |
8450 | |
8451 | if (FT->getNumParams() != 1) |
8452 | return QualType(); |
8453 | |
8454 | return FT->getParamType(0); |
8455 | } |
8456 | |
8457 | |
8458 | |
8459 | static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, |
8460 | unsigned AbsFunctionKind) { |
8461 | unsigned BestKind = 0; |
8462 | uint64_t ArgSize = Context.getTypeSize(ArgType); |
8463 | for (unsigned Kind = AbsFunctionKind; Kind != 0; |
8464 | Kind = getLargerAbsoluteValueFunction(Kind)) { |
8465 | QualType ParamType = getAbsoluteValueArgumentType(Context, Kind); |
8466 | if (Context.getTypeSize(ParamType) >= ArgSize) { |
8467 | if (BestKind == 0) |
8468 | BestKind = Kind; |
8469 | else if (Context.hasSameType(ParamType, ArgType)) { |
8470 | BestKind = Kind; |
8471 | break; |
8472 | } |
8473 | } |
8474 | } |
8475 | return BestKind; |
8476 | } |
8477 | |
8478 | enum AbsoluteValueKind { |
8479 | AVK_Integer, |
8480 | AVK_Floating, |
8481 | AVK_Complex |
8482 | }; |
8483 | |
8484 | static AbsoluteValueKind getAbsoluteValueKind(QualType T) { |
8485 | if (T->isIntegralOrEnumerationType()) |
8486 | return AVK_Integer; |
8487 | if (T->isRealFloatingType()) |
8488 | return AVK_Floating; |
8489 | if (T->isAnyComplexType()) |
8490 | return AVK_Complex; |
8491 | |
8492 | llvm_unreachable("Type not integer, floating, or complex"); |
8493 | } |
8494 | |
8495 | |
8496 | |
8497 | static unsigned changeAbsFunction(unsigned AbsKind, |
8498 | AbsoluteValueKind ValueKind) { |
8499 | switch (ValueKind) { |
8500 | case AVK_Integer: |
8501 | switch (AbsKind) { |
8502 | default: |
8503 | return 0; |
8504 | case Builtin::BI__builtin_fabsf: |
8505 | case Builtin::BI__builtin_fabs: |
8506 | case Builtin::BI__builtin_fabsl: |
8507 | case Builtin::BI__builtin_cabsf: |
8508 | case Builtin::BI__builtin_cabs: |
8509 | case Builtin::BI__builtin_cabsl: |
8510 | return Builtin::BI__builtin_abs; |
8511 | case Builtin::BIfabsf: |
8512 | case Builtin::BIfabs: |
8513 | case Builtin::BIfabsl: |
8514 | case Builtin::BIcabsf: |
8515 | case Builtin::BIcabs: |
8516 | case Builtin::BIcabsl: |
8517 | return Builtin::BIabs; |
8518 | } |
8519 | case AVK_Floating: |
8520 | switch (AbsKind) { |
8521 | default: |
8522 | return 0; |
8523 | case Builtin::BI__builtin_abs: |
8524 | case Builtin::BI__builtin_labs: |
8525 | case Builtin::BI__builtin_llabs: |
8526 | case Builtin::BI__builtin_cabsf: |
8527 | case Builtin::BI__builtin_cabs: |
8528 | case Builtin::BI__builtin_cabsl: |
8529 | return Builtin::BI__builtin_fabsf; |
8530 | case Builtin::BIabs: |
8531 | case Builtin::BIlabs: |
8532 | case Builtin::BIllabs: |
8533 | case Builtin::BIcabsf: |
8534 | case Builtin::BIcabs: |
8535 | case Builtin::BIcabsl: |
8536 | return Builtin::BIfabsf; |
8537 | } |
8538 | case AVK_Complex: |
8539 | switch (AbsKind) { |
8540 | default: |
8541 | return 0; |
8542 | case Builtin::BI__builtin_abs: |
8543 | case Builtin::BI__builtin_labs: |
8544 | case Builtin::BI__builtin_llabs: |
8545 | case Builtin::BI__builtin_fabsf: |
8546 | case Builtin::BI__builtin_fabs: |
8547 | case Builtin::BI__builtin_fabsl: |
8548 | return Builtin::BI__builtin_cabsf; |
8549 | case Builtin::BIabs: |
8550 | case Builtin::BIlabs: |
8551 | case Builtin::BIllabs: |
8552 | case Builtin::BIfabsf: |
8553 | case Builtin::BIfabs: |
8554 | case Builtin::BIfabsl: |
8555 | return Builtin::BIcabsf; |
8556 | } |
8557 | } |
8558 | llvm_unreachable("Unable to convert function"); |
8559 | } |
8560 | |
8561 | static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl) { |
8562 | const IdentifierInfo *FnInfo = FDecl->getIdentifier(); |
8563 | if (!FnInfo) |
8564 | return 0; |
8565 | |
8566 | switch (FDecl->getBuiltinID()) { |
8567 | default: |
8568 | return 0; |
8569 | case Builtin::BI__builtin_abs: |
8570 | case Builtin::BI__builtin_fabs: |
8571 | case Builtin::BI__builtin_fabsf: |
8572 | case Builtin::BI__builtin_fabsl: |
8573 | case Builtin::BI__builtin_labs: |
8574 | case Builtin::BI__builtin_llabs: |
8575 | case Builtin::BI__builtin_cabs: |
8576 | case Builtin::BI__builtin_cabsf: |
8577 | case Builtin::BI__builtin_cabsl: |
8578 | case Builtin::BIabs: |
8579 | case Builtin::BIlabs: |
8580 | case Builtin::BIllabs: |
8581 | case Builtin::BIfabs: |
8582 | case Builtin::BIfabsf: |
8583 | case Builtin::BIfabsl: |
8584 | case Builtin::BIcabs: |
8585 | case Builtin::BIcabsf: |
8586 | case Builtin::BIcabsl: |
8587 | return FDecl->getBuiltinID(); |
8588 | } |
8589 | llvm_unreachable("Unknown Builtin type"); |
8590 | } |
8591 | |
8592 | |
8593 | |
8594 | static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, |
8595 | unsigned AbsKind, QualType ArgType) { |
8596 | bool = true; |
8597 | const char * = nullptr; |
8598 | const char *FunctionName = nullptr; |
8599 | if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) { |
8600 | FunctionName = "std::abs"; |
8601 | if (ArgType->isIntegralOrEnumerationType()) { |
8602 | HeaderName = "cstdlib"; |
8603 | } else if (ArgType->isRealFloatingType()) { |
8604 | HeaderName = "cmath"; |
8605 | } else { |
8606 | llvm_unreachable("Invalid Type"); |
8607 | } |
8608 | |
8609 | |
8610 | if (NamespaceDecl *Std = S.getStdNamespace()) { |
8611 | LookupResult R(S, &S.Context.Idents.get("abs"), Loc, Sema::LookupAnyName); |
8612 | R.suppressDiagnostics(); |
8613 | S.LookupQualifiedName(R, Std); |
8614 | |
8615 | for (const auto *I : R) { |
8616 | const FunctionDecl *FDecl = nullptr; |
8617 | if (const UsingShadowDecl *UsingD = dyn_cast<UsingShadowDecl>(I)) { |
8618 | FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl()); |
8619 | } else { |
8620 | FDecl = dyn_cast<FunctionDecl>(I); |
8621 | } |
8622 | if (!FDecl) |
8623 | continue; |
8624 | |
8625 | |
8626 | if (FDecl->getNumParams() != 1) |
8627 | continue; |
8628 | |
8629 | |
8630 | QualType ParamType = FDecl->getParamDecl(0)->getType(); |
8631 | if (getAbsoluteValueKind(ArgType) == getAbsoluteValueKind(ParamType) && |
8632 | S.Context.getTypeSize(ArgType) <= |
8633 | S.Context.getTypeSize(ParamType)) { |
8634 | |
8635 | EmitHeaderHint = false; |
8636 | break; |
8637 | } |
8638 | } |
8639 | } |
8640 | } else { |
8641 | FunctionName = S.Context.BuiltinInfo.getName(AbsKind); |
8642 | HeaderName = S.Context.BuiltinInfo.getHeaderName(AbsKind); |
8643 | |
8644 | if (HeaderName) { |
8645 | DeclarationName DN(&S.Context.Idents.get(FunctionName)); |
8646 | LookupResult R(S, DN, Loc, Sema::LookupAnyName); |
8647 | R.suppressDiagnostics(); |
8648 | S.LookupName(R, S.getCurScope()); |
8649 | |
8650 | if (R.isSingleResult()) { |
8651 | FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl()); |
8652 | if (FD && FD->getBuiltinID() == AbsKind) { |
8653 | EmitHeaderHint = false; |
8654 | } else { |
8655 | return; |
8656 | } |
8657 | } else if (!R.empty()) { |
8658 | return; |
8659 | } |
8660 | } |
8661 | } |
8662 | |
8663 | S.Diag(Loc, diag::note_replace_abs_function) |
8664 | << FunctionName << FixItHint::CreateReplacement(Range, FunctionName); |
8665 | |
8666 | if (!HeaderName) |
8667 | return; |
8668 | |
8669 | if (!EmitHeaderHint) |
8670 | return; |
8671 | |
8672 | S.Diag(Loc, diag::note_include_header_or_declare) << HeaderName |
8673 | << FunctionName; |
8674 | } |
8675 | |
8676 | template <std::size_t StrLen> |
8677 | static bool IsStdFunction(const FunctionDecl *FDecl, |
8678 | const char (&Str)[StrLen]) { |
8679 | if (!FDecl) |
8680 | return false; |
8681 | if (!FDecl->getIdentifier() || !FDecl->getIdentifier()->isStr(Str)) |
8682 | return false; |
8683 | if (!FDecl->isInStdNamespace()) |
8684 | return false; |
8685 | |
8686 | return true; |
8687 | } |
8688 | |
8689 | |
8690 | void Sema::CheckAbsoluteValueFunction(const CallExpr *Call, |
8691 | const FunctionDecl *FDecl) { |
8692 | if (Call->getNumArgs() != 1) |
8693 | return; |
8694 | |
8695 | unsigned AbsKind = getAbsoluteValueFunctionKind(FDecl); |
8696 | bool IsStdAbs = IsStdFunction(FDecl, "abs"); |
8697 | if (AbsKind == 0 && !IsStdAbs) |
8698 | return; |
8699 | |
8700 | QualType ArgType = Call->getArg(0)->IgnoreParenImpCasts()->getType(); |
8701 | QualType ParamType = Call->getArg(0)->getType(); |
8702 | |
8703 | |
8704 | |
8705 | if (ArgType->isUnsignedIntegerType()) { |
8706 | const char *FunctionName = |
8707 | IsStdAbs ? "std::abs" : Context.BuiltinInfo.getName(AbsKind); |
8708 | Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType; |
8709 | Diag(Call->getExprLoc(), diag::note_remove_abs) |
8710 | << FunctionName |
8711 | << FixItHint::CreateRemoval(Call->getCallee()->getSourceRange()); |
8712 | return; |
8713 | } |
8714 | |
8715 | |
8716 | |
8717 | if (ArgType->isPointerType() || ArgType->canDecayToPointerType()) { |
8718 | unsigned DiagType = 0; |
8719 | if (ArgType->isFunctionType()) |
8720 | DiagType = 1; |
8721 | else if (ArgType->isArrayType()) |
8722 | DiagType = 2; |
8723 | |
8724 | Diag(Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType; |
8725 | return; |
8726 | } |
8727 | |
8728 | |
8729 | |
8730 | if (IsStdAbs) |
8731 | return; |
8732 | |
8733 | AbsoluteValueKind ArgValueKind = getAbsoluteValueKind(ArgType); |
8734 | AbsoluteValueKind ParamValueKind = getAbsoluteValueKind(ParamType); |
8735 | |
8736 | |
8737 | |
8738 | if (ArgValueKind == ParamValueKind) { |
8739 | if (Context.getTypeSize(ArgType) <= Context.getTypeSize(ParamType)) |
8740 | return; |
8741 | |
8742 | unsigned NewAbsKind = getBestAbsFunction(Context, ArgType, AbsKind); |
8743 | Diag(Call->getExprLoc(), diag::warn_abs_too_small) |
8744 | << FDecl << ArgType << ParamType; |
8745 | |
8746 | if (NewAbsKind == 0) |
8747 | return; |
8748 | |
8749 | emitReplacement(*this, Call->getExprLoc(), |
8750 | Call->getCallee()->getSourceRange(), NewAbsKind, ArgType); |
8751 | return; |
8752 | } |
8753 | |
8754 | |
8755 | |
8756 | |
8757 | unsigned NewAbsKind = changeAbsFunction(AbsKind, ArgValueKind); |
8758 | NewAbsKind = getBestAbsFunction(Context, ArgType, NewAbsKind); |
8759 | if (NewAbsKind == 0) |
8760 | return; |
8761 | |
8762 | Diag(Call->getExprLoc(), diag::warn_wrong_absolute_value_type) |
8763 | << FDecl << ParamValueKind << ArgValueKind; |
8764 | |
8765 | emitReplacement(*this, Call->getExprLoc(), |
8766 | Call->getCallee()->getSourceRange(), NewAbsKind, ArgType); |
8767 | } |
8768 | |
8769 | |
8770 | void Sema::CheckMaxUnsignedZero(const CallExpr *Call, |
8771 | const FunctionDecl *FDecl) { |
8772 | if (!Call || !FDecl) return; |
8773 | |
8774 | |
8775 | if (inTemplateInstantiation()) return; |
8776 | if (Call->getExprLoc().isMacroID()) return; |
8777 | |
8778 | |
8779 | if (Call->getNumArgs() != 2) return; |
8780 | if (!IsStdFunction(FDecl, "max")) return; |
8781 | const auto * ArgList = FDecl->getTemplateSpecializationArgs(); |
8782 | if (!ArgList) return; |
8783 | if (ArgList->size() != 1) return; |
8784 | |
8785 | |
8786 | const auto& TA = ArgList->get(0); |
8787 | if (TA.getKind() != TemplateArgument::Type) return; |
8788 | QualType ArgType = TA.getAsType(); |
8789 | if (!ArgType->isUnsignedIntegerType()) return; |
8790 | |
8791 | |
8792 | auto IsLiteralZeroArg = [](const Expr* E) -> bool { |
8793 | const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E); |
8794 | if (!MTE) return false; |
8795 | const auto *Num = dyn_cast<IntegerLiteral>(MTE->GetTemporaryExpr()); |
8796 | if (!Num) return false; |
8797 | if (Num->getValue() != 0) return false; |
8798 | return true; |
8799 | }; |
8800 | |
8801 | const Expr *FirstArg = Call->getArg(0); |
8802 | const Expr *SecondArg = Call->getArg(1); |
8803 | const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg); |
8804 | const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg); |
8805 | |
8806 | |
8807 | if (IsFirstArgZero == IsSecondArgZero) return; |
8808 | |
8809 | SourceRange FirstRange = FirstArg->getSourceRange(); |
8810 | SourceRange SecondRange = SecondArg->getSourceRange(); |
8811 | |
8812 | SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange; |
8813 | |
8814 | Diag(Call->getExprLoc(), diag::warn_max_unsigned_zero) |
8815 | << IsFirstArgZero << Call->getCallee()->getSourceRange() << ZeroRange; |
8816 | |
8817 | |
8818 | SourceRange RemovalRange; |
8819 | if (IsFirstArgZero) { |
8820 | RemovalRange = SourceRange(FirstRange.getBegin(), |
8821 | SecondRange.getBegin().getLocWithOffset(-1)); |
8822 | } else { |
8823 | RemovalRange = SourceRange(getLocForEndOfToken(FirstRange.getEnd()), |
8824 | SecondRange.getEnd()); |
8825 | } |
8826 | |
8827 | Diag(Call->getExprLoc(), diag::note_remove_max_call) |
8828 | << FixItHint::CreateRemoval(Call->getCallee()->getSourceRange()) |
8829 | << FixItHint::CreateRemoval(RemovalRange); |
8830 | } |
8831 | |
8832 | |
8833 | |
8834 | |
8835 | |
8836 | |
8837 | |
8838 | static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, |
8839 | IdentifierInfo *FnName, |
8840 | SourceLocation FnLoc, |
8841 | SourceLocation RParenLoc) { |
8842 | const BinaryOperator *Size = dyn_cast<BinaryOperator>(E); |
8843 | if (!Size) |
8844 | return false; |
8845 | |
8846 | |
8847 | if (!Size->isComparisonOp() && !Size->isLogicalOp()) |
8848 | return false; |
8849 | |
8850 | SourceRange SizeRange = Size->getSourceRange(); |
8851 | S.Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison) |
8852 | << SizeRange << FnName; |
8853 | S.Diag(FnLoc, diag::note_memsize_comparison_paren) |
8854 | << FnName |
8855 | << FixItHint::CreateInsertion( |
8856 | S.getLocForEndOfToken(Size->getLHS()->getEndLoc()), ")") |
8857 | << FixItHint::CreateRemoval(RParenLoc); |
8858 | S.Diag(SizeRange.getBegin(), diag::note_memsize_comparison_cast_silence) |
8859 | << FixItHint::CreateInsertion(SizeRange.getBegin(), "(size_t)(") |
8860 | << FixItHint::CreateInsertion(S.getLocForEndOfToken(SizeRange.getEnd()), |
8861 | ")"); |
8862 | |
8863 | return true; |
8864 | } |
8865 | |
8866 | |
8867 | |
8868 | static const CXXRecordDecl *getContainedDynamicClass(QualType T, |
8869 | bool &IsContained) { |
8870 | |
8871 | const Type *Ty = T->getBaseElementTypeUnsafe(); |
8872 | IsContained = false; |
8873 | |
8874 | const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); |
8875 | RD = RD ? RD->getDefinition() : nullptr; |
8876 | if (!RD || RD->isInvalidDecl()) |
8877 | return nullptr; |
8878 | |
8879 | if (RD->isDynamicClass()) |
8880 | return RD; |
8881 | |
8882 | |
8883 | |
8884 | |
8885 | for (auto *FD : RD->fields()) { |
8886 | bool SubContained; |
8887 | if (const CXXRecordDecl *ContainedRD = |
8888 | getContainedDynamicClass(FD->getType(), SubContained)) { |
8889 | IsContained = true; |
8890 | return ContainedRD; |
8891 | } |
8892 | } |
8893 | |
8894 | return nullptr; |
8895 | } |
8896 | |
8897 | static const UnaryExprOrTypeTraitExpr *getAsSizeOfExpr(const Expr *E) { |
8898 | if (const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E)) |
8899 | if (Unary->getKind() == UETT_SizeOf) |
8900 | return Unary; |
8901 | return nullptr; |
8902 | } |
8903 | |
8904 | |
8905 | |
8906 | static const Expr *getSizeOfExprArg(const Expr *E) { |
8907 | if (const UnaryExprOrTypeTraitExpr *SizeOf = getAsSizeOfExpr(E)) |
8908 | if (!SizeOf->isArgumentType()) |
8909 | return SizeOf->getArgumentExpr()->IgnoreParenImpCasts(); |
8910 | return nullptr; |
8911 | } |
8912 | |
8913 | |
8914 | static QualType getSizeOfArgType(const Expr *E) { |
8915 | if (const UnaryExprOrTypeTraitExpr *SizeOf = getAsSizeOfExpr(E)) |
8916 | return SizeOf->getTypeOfArgument(); |
8917 | return QualType(); |
8918 | } |
8919 | |
8920 | namespace { |
8921 | |
8922 | struct SearchNonTrivialToInitializeField |
8923 | : DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField> { |
8924 | using Super = |
8925 | DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>; |
8926 | |
8927 | SearchNonTrivialToInitializeField(const Expr *E, Sema &S) : E(E), S(S) {} |
8928 | |
8929 | void visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK, QualType FT, |
8930 | SourceLocation SL) { |
8931 | if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) { |
8932 | asDerived().visitArray(PDIK, AT, SL); |
8933 | return; |
8934 | } |
8935 | |
8936 | Super::visitWithKind(PDIK, FT, SL); |
8937 | } |
8938 | |
8939 | void visitARCStrong(QualType FT, SourceLocation SL) { |
8940 | S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 1); |
8941 | } |
8942 | void visitARCWeak(QualType FT, SourceLocation SL) { |
8943 | S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 1); |
8944 | } |
8945 | void visitStruct(QualType FT, SourceLocation SL) { |
8946 | for (const FieldDecl *FD : FT->castAs<RecordType>()->getDecl()->fields()) |
8947 | visit(FD->getType(), FD->getLocation()); |
8948 | } |
8949 | void visitArray(QualType::PrimitiveDefaultInitializeKind PDIK, |
8950 | const ArrayType *AT, SourceLocation SL) { |
8951 | visit(getContext().getBaseElementType(AT), SL); |
8952 | } |
8953 | void visitTrivial(QualType FT, SourceLocation SL) {} |
8954 | |
8955 | static void diag(QualType RT, const Expr *E, Sema &S) { |
8956 | SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation()); |
8957 | } |
8958 | |
8959 | ASTContext &getContext() { return S.getASTContext(); } |
8960 | |
8961 | const Expr *E; |
8962 | Sema &S; |
8963 | }; |
8964 | |
8965 | struct SearchNonTrivialToCopyField |
8966 | : CopiedTypeVisitor<SearchNonTrivialToCopyField, false> { |
8967 | using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>; |
8968 | |
8969 | SearchNonTrivialToCopyField(const Expr *E, Sema &S) : E(E), S(S) {} |
8970 | |
8971 | void visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT, |
8972 | SourceLocation SL) { |
8973 | if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) { |
8974 | asDerived().visitArray(PCK, AT, SL); |
8975 | return; |
8976 | } |
8977 | |
8978 | Super::visitWithKind(PCK, FT, SL); |
8979 | } |
8980 | |
8981 | void visitARCStrong(QualType FT, SourceLocation SL) { |
8982 | S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 0); |
8983 | } |
8984 | void visitARCWeak(QualType FT, SourceLocation SL) { |
8985 | S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 0); |
8986 | } |
8987 | void visitStruct(QualType FT, SourceLocation SL) { |
8988 | for (const FieldDecl *FD : FT->castAs<RecordType>()->getDecl()->fields()) |
8989 | visit(FD->getType(), FD->getLocation()); |
8990 | } |
8991 | void visitArray(QualType::PrimitiveCopyKind PCK, const ArrayType *AT, |
8992 | SourceLocation SL) { |
8993 | visit(getContext().getBaseElementType(AT), SL); |
8994 | } |
8995 | void preVisit(QualType::PrimitiveCopyKind PCK, QualType FT, |
8996 | SourceLocation SL) {} |
8997 | void visitTrivial(QualType FT, SourceLocation SL) {} |
8998 | void visitVolatileTrivial(QualType FT, SourceLocation SL) {} |
8999 | |
9000 | static void diag(QualType RT, const Expr *E, Sema &S) { |
9001 | SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation()); |
9002 | } |
9003 | |
9004 | ASTContext &getContext() { return S.getASTContext(); } |
9005 | |
9006 | const Expr *E; |
9007 | Sema &S; |
9008 | }; |
9009 | |
9010 | } |
9011 | |
9012 | |
9013 | static bool doesExprLikelyComputeSize(const Expr *SizeofExpr) { |
9014 | SizeofExpr = SizeofExpr->IgnoreParenImpCasts(); |
9015 | |
9016 | if (const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) { |
9017 | if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add) |
9018 | return false; |
9019 | |
9020 | return doesExprLikelyComputeSize(BO->getLHS()) || |
9021 | doesExprLikelyComputeSize(BO->getRHS()); |
9022 | } |
9023 | |
9024 | return getAsSizeOfExpr(SizeofExpr) != nullptr; |
9025 | } |
9026 | |
9027 | |
9028 | |
9029 | |
9030 | |
9031 | |
9032 | |
9033 | |
9034 | |
9035 | |
9036 | |
9037 | static bool isArgumentExpandedFromMacro(SourceManager &SM, |
9038 | SourceLocation CallLoc, |
9039 | SourceLocation ArgLoc) { |
9040 | if (!CallLoc.isMacroID()) |
9041 | return SM.getFileID(CallLoc) != SM.getFileID(ArgLoc); |
9042 | |
9043 | return SM.getFileID(SM.getImmediateMacroCallerLoc(CallLoc)) != |
9044 | SM.getFileID(SM.getImmediateMacroCallerLoc(ArgLoc)); |
9045 | } |
9046 | |
9047 | |
9048 | |
9049 | static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call) { |
9050 | if (BId != Builtin::BImemset && BId != Builtin::BIbzero) |
9051 | return; |
9052 | |
9053 | const Expr *SizeArg = |
9054 | Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts(); |
9055 | |
9056 | auto isLiteralZero = [](const Expr *E) { |
9057 | return isa<IntegerLiteral>(E) && cast<IntegerLiteral>(E)->getValue() == 0; |
9058 | }; |
9059 | |
9060 | |
9061 | SourceLocation CallLoc = Call->getRParenLoc(); |
9062 | SourceManager &SM = S.getSourceManager(); |
9063 | if (isLiteralZero(SizeArg) && |
9064 | !isArgumentExpandedFromMacro(SM, CallLoc, SizeArg->getExprLoc())) { |
9065 | |
9066 | SourceLocation DiagLoc = SizeArg->getExprLoc(); |
9067 | |
9068 | |
9069 | |
9070 | if (BId == Builtin::BIbzero || |
9071 | (CallLoc.isMacroID() && Lexer::getImmediateMacroName( |
9072 | CallLoc, SM, S.getLangOpts()) == "bzero")) { |
9073 | S.Diag(DiagLoc, diag::warn_suspicious_bzero_size); |
9074 | S.Diag(DiagLoc, diag::note_suspicious_bzero_size_silence); |
9075 | } else if (!isLiteralZero(Call->getArg(1)->IgnoreImpCasts())) { |
9076 | S.Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0; |
9077 | S.Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0; |
9078 | } |
9079 | return; |
9080 | } |
9081 | |
9082 | |
9083 | |
9084 | |
9085 | if (BId == Builtin::BImemset && |
9086 | doesExprLikelyComputeSize(Call->getArg(1)) && |
9087 | !doesExprLikelyComputeSize(Call->getArg(2))) { |
9088 | SourceLocation DiagLoc = Call->getArg(1)->getExprLoc(); |
9089 | S.Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1; |
9090 | S.Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1; |
9091 | return; |
9092 | } |
9093 | } |
9094 | |
9095 | |
9096 | |
9097 | |
9098 | |
9099 | |
9100 | |
9101 | |
9102 | void Sema::CheckMemaccessArguments(const CallExpr *Call, |
9103 | unsigned BId, |
9104 | IdentifierInfo *FnName) { |
9105 | assert(BId != 0); |
9106 | |
9107 | |
9108 | |
9109 | unsigned ExpectedNumArgs = |
9110 | (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3); |
9111 | if (Call->getNumArgs() < ExpectedNumArgs) |
9112 | return; |
9113 | |
9114 | unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero || |
9115 | BId == Builtin::BIstrndup ? 1 : 2); |
9116 | unsigned LenArg = |
9117 | (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2); |
9118 | const Expr *LenExpr = Call->getArg(LenArg)->IgnoreParenImpCasts(); |
9119 | |
9120 | if (CheckMemorySizeofForComparison(*this, LenExpr, FnName, |
9121 | Call->getBeginLoc(), Call->getRParenLoc())) |
9122 | return; |
9123 | |
9124 | |
9125 | CheckMemaccessSize(*this, BId, Call); |
9126 | |
9127 | |
9128 | QualType SizeOfArgTy = getSizeOfArgType(LenExpr); |
9129 | const Expr *SizeOfArg = getSizeOfExprArg(LenExpr); |
9130 | llvm::FoldingSetNodeID SizeOfArgID; |
9131 | |
9132 | |
9133 | |
9134 | |
9135 | QualType FirstArgTy = Call->getArg(0)->IgnoreParenImpCasts()->getType(); |
9136 | if (BId == Builtin::BIbzero && !FirstArgTy->getAs<PointerType>()) |
9137 | return; |
9138 | |
9139 | for (unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) { |
9140 | const Expr *Dest = Call->getArg(ArgIdx)->IgnoreParenImpCasts(); |
9141 | SourceRange ArgRange = Call->getArg(ArgIdx)->getSourceRange(); |
9142 | |
9143 | QualType DestTy = Dest->getType(); |
9144 | QualType PointeeTy; |
9145 | if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) { |
9146 | PointeeTy = DestPtrTy->getPointeeType(); |
9147 | |
9148 | |
9149 | |
9150 | if (PointeeTy->isVoidType()) |
9151 | continue; |
9152 | |
9153 | |
9154 | |
9155 | |
9156 | |
9157 | if (SizeOfArg && |
9158 | !Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, |
9159 | SizeOfArg->getExprLoc())) { |
9160 | |
9161 | |
9162 | if (SizeOfArgID == llvm::FoldingSetNodeID()) |
9163 | SizeOfArg->Profile(SizeOfArgID, Context, true); |
9164 | llvm::FoldingSetNodeID DestID; |
9165 | Dest->Profile(DestID, Context, true); |
9166 | if (DestID == SizeOfArgID) { |
9167 | |
9168 | |
9169 | unsigned ActionIdx = 0; |
9170 | StringRef ReadableName = FnName->getName(); |
9171 | |
9172 | if (const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest)) |
9173 | if (UnaryOp->getOpcode() == UO_AddrOf) |
9174 | ActionIdx = 1; |
9175 | if (!PointeeTy->isIncompleteType() && |
9176 | (Context.getTypeSize(PointeeTy) == Context.getCharWidth())) |
9177 | ActionIdx = 2; |
9178 | |
9179 | |
9180 | |
9181 | |
9182 | SourceLocation SL = SizeOfArg->getExprLoc(); |
9183 | SourceRange DSR = Dest->getSourceRange(); |
9184 | SourceRange SSR = SizeOfArg->getSourceRange(); |
9185 | SourceManager &SM = getSourceManager(); |
9186 | |
9187 | if (SM.isMacroArgExpansion(SL)) { |
9188 | ReadableName = Lexer::getImmediateMacroName(SL, SM, LangOpts); |
9189 | SL = SM.getSpellingLoc(SL); |
9190 | DSR = SourceRange(SM.getSpellingLoc(DSR.getBegin()), |
9191 | SM.getSpellingLoc(DSR.getEnd())); |
9192 | SSR = SourceRange(SM.getSpellingLoc(SSR.getBegin()), |
9193 | SM.getSpellingLoc(SSR.getEnd())); |
9194 | } |
9195 | |
9196 | DiagRuntimeBehavior(SL, SizeOfArg, |
9197 | PDiag(diag::warn_sizeof_pointer_expr_memaccess) |
9198 | << ReadableName |
9199 | << PointeeTy |
9200 | << DestTy |
9201 | << DSR |
9202 | << SSR); |
9203 | DiagRuntimeBehavior(SL, SizeOfArg, |
9204 | PDiag(diag::warn_sizeof_pointer_expr_memaccess_note) |
9205 | << ActionIdx |
9206 | << SSR); |
9207 | |
9208 | break; |
9209 | } |
9210 | } |
9211 | |
9212 | |
9213 | |
9214 | |
9215 | if (SizeOfArgTy != QualType()) { |
9216 | if (PointeeTy->isRecordType() && |
9217 | Context.typesAreCompatible(SizeOfArgTy, DestTy)) { |
9218 | DiagRuntimeBehavior(LenExpr->getExprLoc(), Dest, |
9219 | PDiag(diag::warn_sizeof_pointer_type_memaccess) |
9220 | << FnName << SizeOfArgTy << ArgIdx |
9221 | << PointeeTy << Dest->getSourceRange() |
9222 | << LenExpr->getSourceRange()); |
9223 | break; |
9224 | } |
9225 | } |
9226 | } else if (DestTy->isArrayType()) { |
9227 | PointeeTy = DestTy; |
9228 | } |
9229 | |
9230 | if (PointeeTy == QualType()) |
9231 | continue; |
9232 | |
9233 | |
9234 | bool IsContained; |
9235 | if (const CXXRecordDecl *ContainedRD = |
9236 | getContainedDynamicClass(PointeeTy, IsContained)) { |
9237 | |
9238 | unsigned OperationType = 0; |
9239 | const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp; |
9240 | |
9241 | |
9242 | if (ArgIdx != 0 || IsCmp) { |
9243 | if (BId == Builtin::BImemcpy) |
9244 | OperationType = 1; |
9245 | else if(BId == Builtin::BImemmove) |
9246 | OperationType = 2; |
9247 | else if (IsCmp) |
9248 | OperationType = 3; |
9249 | } |
9250 | |
9251 | DiagRuntimeBehavior(Dest->getExprLoc(), Dest, |
9252 | PDiag(diag::warn_dyn_class_memaccess) |
9253 | << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName |
9254 | << IsContained << ContainedRD << OperationType |
9255 | << Call->getCallee()->getSourceRange()); |
9256 | } else if (PointeeTy.hasNonTrivialObjCLifetime() && |
9257 | BId != Builtin::BImemset) |
9258 | DiagRuntimeBehavior( |
9259 | Dest->getExprLoc(), Dest, |
9260 | PDiag(diag::warn_arc_object_memaccess) |
9261 | << ArgIdx << FnName << PointeeTy |
9262 | << Call->getCallee()->getSourceRange()); |
9263 | else if (const auto *RT = PointeeTy->getAs<RecordType>()) { |
9264 | if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) && |
9265 | RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) { |
9266 | DiagRuntimeBehavior(Dest->getExprLoc(), Dest, |
9267 | PDiag(diag::warn_cstruct_memaccess) |
9268 | << ArgIdx << FnName << PointeeTy << 0); |
9269 | SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *this); |
9270 | } else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) && |
9271 | RT->getDecl()->isNonTrivialToPrimitiveCopy()) { |
9272 | DiagRuntimeBehavior(Dest->getExprLoc(), Dest, |
9273 | PDiag(diag::warn_cstruct_memaccess) |
9274 | << ArgIdx << FnName << PointeeTy << 1); |
9275 | SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *this); |
9276 | } else { |
9277 | continue; |
9278 | } |
9279 | } else |
9280 | continue; |
9281 | |
9282 | DiagRuntimeBehavior( |
9283 | Dest->getExprLoc(), Dest, |
9284 | PDiag(diag::note_bad_memaccess_silence) |
9285 | << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)")); |
9286 | break; |
9287 | } |
9288 | } |
9289 | |
9290 | |
9291 | |
9292 | |
9293 | static const Expr *ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx) { |
9294 | Ex = Ex->IgnoreParenCasts(); |
9295 | |
9296 | while (true) { |
9297 | const BinaryOperator * BO = dyn_cast<BinaryOperator>(Ex); |
9298 | if (!BO || !BO->isAdditiveOp()) |
9299 | break; |
9300 | |
9301 | const Expr *RHS = BO->getRHS()->IgnoreParenCasts(); |
9302 | const Expr *LHS = BO->getLHS()->IgnoreParenCasts(); |
9303 | |
9304 | if (isa<IntegerLiteral>(RHS)) |
9305 | Ex = LHS; |
9306 | else if (isa<IntegerLiteral>(LHS)) |
9307 | Ex = RHS; |
9308 | else |
9309 | break; |
9310 | } |
9311 | |
9312 | return Ex; |
9313 | } |
9314 | |
9315 | static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, |
9316 | ASTContext &Context) { |
9317 | |
9318 | if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(Ty)) { |
9319 | |
9320 | if (CAT->getSize().getSExtValue() <= 1) |
9321 | return false; |
9322 | } else if (!Ty->isVariableArrayType()) { |
9323 | return false; |
9324 | } |
9325 | return true; |
9326 | } |
9327 | |
9328 | |
9329 | |
9330 | void Sema::CheckStrlcpycatArguments(const CallExpr *Call, |
9331 | IdentifierInfo *FnName) { |
9332 | |
9333 | |
9334 | unsigned NumArgs = Call->getNumArgs(); |
9335 | if ((NumArgs != 3) && (NumArgs != 4)) |
9336 | return; |
9337 | |
9338 | const Expr *SrcArg = ignoreLiteralAdditions(Call->getArg(1), Context); |
9339 | const Expr *SizeArg = ignoreLiteralAdditions(Call->getArg(2), Context); |
9340 | const Expr *CompareWithSrc = nullptr; |
9341 | |
9342 | if (CheckMemorySizeofForComparison(*this, SizeArg, FnName, |
9343 | Call->getBeginLoc(), Call->getRParenLoc())) |
9344 | return; |
9345 | |
9346 | |
9347 | if (const Expr *Ex = getSizeOfExprArg(SizeArg)) |
9348 | CompareWithSrc = Ex; |
9349 | else { |
9350 | |
9351 | if (const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) { |
9352 | if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen && |
9353 | SizeCall->getNumArgs() == 1) |
9354 | CompareWithSrc = ignoreLiteralAdditions(SizeCall->getArg(0), Context); |
9355 | } |
9356 | } |
9357 | |
9358 | if (!CompareWithSrc) |
9359 | return; |
9360 | |
9361 | |
9362 | |
9363 | |
9364 | |
9365 | const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg); |
9366 | if (!SrcArgDRE) |
9367 | return; |
9368 | |
9369 | const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc); |
9370 | if (!CompareWithSrcDRE || |
9371 | SrcArgDRE->getDecl() != CompareWithSrcDRE->getDecl()) |
9372 | return; |
9373 | |
9374 | const Expr *OriginalSizeArg = Call->getArg(2); |
9375 | Diag(CompareWithSrcDRE->getBeginLoc(), diag::warn_strlcpycat_wrong_size) |
9376 | << OriginalSizeArg->getSourceRange() << FnName; |
9377 | |
9378 | |
9379 | |
9380 | |
9381 | |
9382 | const Expr *DstArg = Call->getArg(0)->IgnoreParenImpCasts(); |
9383 | if (!isConstantSizeArrayWithMoreThanOneElement(DstArg->getType(), Context)) |
9384 | return; |
9385 | |
9386 | SmallString<128> sizeString; |
9387 | llvm::raw_svector_ostream OS(sizeString); |
9388 | OS << "sizeof("; |
9389 | DstArg->printPretty(OS, nullptr, getPrintingPolicy()); |
9390 | OS << ")"; |
9391 | |
9392 | Diag(OriginalSizeArg->getBeginLoc(), diag::note_strlcpycat_wrong_size) |
9393 | << FixItHint::CreateReplacement(OriginalSizeArg->getSourceRange(), |
9394 | OS.str()); |
9395 | } |
9396 | |
9397 | |
9398 | static bool referToTheSameDecl(const Expr *E1, const Expr *E2) { |
9399 | if (const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1)) |
9400 | if (const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2)) |
9401 | return D1->getDecl() == D2->getDecl(); |
9402 | return false; |
9403 | } |
9404 | |
9405 | static const Expr *getStrlenExprArg(const Expr *E) { |
9406 | if (const CallExpr *CE = dyn_cast<CallExpr>(E)) { |
9407 | const FunctionDecl *FD = CE->getDirectCallee(); |
9408 | if (!FD || FD->getMemoryFunctionKind() != Builtin::BIstrlen) |
9409 | return nullptr; |
9410 | return CE->getArg(0)->IgnoreParenCasts(); |
9411 | } |
9412 | return nullptr; |
9413 | } |
9414 | |
9415 | |
9416 | |
9417 | |
9418 | void Sema::CheckStrncatArguments(const CallExpr *CE, |
9419 | IdentifierInfo *FnName) { |
9420 | |
9421 | if (CE->getNumArgs() < 3) |
9422 | return; |
9423 | const Expr *DstArg = CE->getArg(0)->IgnoreParenCasts(); |
9424 | const Expr *SrcArg = CE->getArg(1)->IgnoreParenCasts(); |
9425 | const Expr *LenArg = CE->getArg(2)->IgnoreParenCasts(); |
9426 | |
9427 | if (CheckMemorySizeofForComparison(*this, LenArg, FnName, CE->getBeginLoc(), |
9428 | CE->getRParenLoc())) |
9429 | return; |
9430 | |
9431 | |
9432 | |
9433 | unsigned PatternType = 0; |
9434 | if (const Expr *SizeOfArg = getSizeOfExprArg(LenArg)) { |
9435 | |
9436 | if (referToTheSameDecl(SizeOfArg, DstArg)) |
9437 | PatternType = 1; |
9438 | |
9439 | else if (referToTheSameDecl(SizeOfArg, SrcArg)) |
9440 | PatternType = 2; |
9441 | } else if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) { |
9442 | if (BE->getOpcode() == BO_Sub) { |
9443 | const Expr *L = BE->getLHS()->IgnoreParenCasts(); |
9444 | const Expr *R = BE->getRHS()->IgnoreParenCasts(); |
9445 | |
9446 | if (referToTheSameDecl(DstArg, getSizeOfExprArg(L)) && |
9447 | referToTheSameDecl(DstArg, getStrlenExprArg(R))) |
9448 | PatternType = 1; |
9449 | |
9450 | else if (referToTheSameDecl(SrcArg, getSizeOfExprArg(L))) |
9451 | PatternType = 2; |
9452 | } |
9453 | } |
9454 | |
9455 | if (PatternType == 0) |
9456 | return; |
9457 | |
9458 | |
9459 | SourceLocation SL = LenArg->getBeginLoc(); |
9460 | SourceRange SR = LenArg->getSourceRange(); |
9461 | SourceManager &SM = getSourceManager(); |
9462 | |
9463 | |
9464 | if (SM.isMacroArgExpansion(SL)) { |
9465 | SL = SM.getSpellingLoc(SL); |
9466 | SR = SourceRange(SM.getSpellingLoc(SR.getBegin()), |
9467 | SM.getSpellingLoc(SR.getEnd())); |
9468 | } |
9469 | |
9470 | |
9471 | QualType DstTy = DstArg->getType(); |
9472 | bool isKnownSizeArray = isConstantSizeArrayWithMoreThanOneElement(DstTy, |
9473 | Context); |
9474 | if (!isKnownSizeArray) { |
9475 | if (PatternType == 1) |
9476 | Diag(SL, diag::warn_strncat_wrong_size) << SR; |
9477 | else |
9478 | Diag(SL, diag::warn_strncat_src_size) << SR; |
9479 | return; |
9480 | } |
9481 | |
9482 | if (PatternType == 1) |
9483 | Diag(SL, diag::warn_strncat_large_size) << SR; |
9484 | else |
9485 | Diag(SL, diag::warn_strncat_src_size) << SR; |
9486 | |
9487 | SmallString<128> sizeString; |
9488 | llvm::raw_svector_ostream OS(sizeString); |
9489 | OS << "sizeof("; |
9490 | DstArg->printPretty(OS, nullptr, getPrintingPolicy()); |
9491 | OS << ") - "; |
9492 | OS << "strlen("; |
9493 | DstArg->printPretty(OS, nullptr, getPrintingPolicy()); |
9494 | OS << ") - 1"; |
9495 | |
9496 | Diag(SL, diag::note_strncat_wrong_size) |
9497 | << FixItHint::CreateReplacement(SR, OS.str()); |
9498 | } |
9499 | |
9500 | void |
9501 | Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType, |
9502 | SourceLocation ReturnLoc, |
9503 | bool isObjCMethod, |
9504 | const AttrVec *Attrs, |
9505 | const FunctionDecl *FD) { |
9506 | |
9507 | if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) || |
9508 | (!isObjCMethod && isNonNullType(Context, lhsType))) && |
9509 | CheckNonNullExpr(*this, RetValExp)) |
9510 | Diag(ReturnLoc, diag::warn_null_ret) |
9511 | << (isObjCMethod ? 1 : 0) << RetValExp->getSourceRange(); |
9512 | |
9513 | |
9514 | |
9515 | |
9516 | |
9517 | |
9518 | if (FD) { |
9519 | OverloadedOperatorKind Op = FD->getOverloadedOperator(); |
9520 | if (Op == OO_New || Op == OO_Array_New) { |
9521 | const FunctionProtoType *Proto |
9522 | = FD->getType()->castAs<FunctionProtoType>(); |
9523 | if (!Proto->isNothrow() && |
9524 | CheckNonNullExpr(*this, RetValExp)) |
9525 | Diag(ReturnLoc, diag::warn_operator_new_returns_null) |
9526 | << FD << getLangOpts().CPlusPlus11; |
9527 | } |
9528 | } |
9529 | } |
9530 | |
9531 | |
9532 | |
9533 | |
9534 | |
9535 | |
9536 | void Sema::CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr *RHS) { |
9537 | Expr* LeftExprSansParen = LHS->IgnoreParenImpCasts(); |
9538 | Expr* RightExprSansParen = RHS->IgnoreParenImpCasts(); |
9539 | |
9540 | |
9541 | |
9542 | if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen)) |
9543 | if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RightExprSansParen)) |
9544 | if (DRL->getDecl() == DRR->getDecl()) |
9545 | return; |
9546 | |
9547 | |
9548 | |
9549 | |
9550 | |
9551 | |
9552 | if (FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) { |
9553 | if (FLL->isExact()) |
9554 | return; |
9555 | } else |
9556 | if (FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen)) |
9557 | if (FLR->isExact()) |
9558 | return; |
9559 | |
9560 | |
9561 | if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen)) |
9562 | if (CL->getBuiltinCallee()) |
9563 | return; |
9564 | |
9565 | if (CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen)) |
9566 | if (CR->getBuiltinCallee()) |
9567 | return; |
9568 | |
9569 | |
9570 | Diag(Loc, diag::warn_floatingpoint_eq) |
9571 | << LHS->getSourceRange() << RHS->getSourceRange(); |
9572 | } |
9573 | |
9574 | |
9575 | |
9576 | |
9577 | namespace { |
9578 | |
9579 | |
9580 | |
9581 | struct IntRange { |
9582 | |
9583 | unsigned Width; |
9584 | |
9585 | |
9586 | bool NonNegative; |
9587 | |
9588 | IntRange(unsigned Width, bool NonNegative) |
9589 | : Width(Width), NonNegative(NonNegative) {} |
9590 | |
9591 | |
9592 | static IntRange forBoolType() { |
9593 | return IntRange(1, true); |
9594 | } |
9595 | |
9596 | |
9597 | static IntRange forValueOfType(ASTContext &C, QualType T) { |
9598 | return forValueOfCanonicalType(C, |
9599 | T->getCanonicalTypeInternal().getTypePtr()); |
9600 | } |
9601 | |
9602 | |
9603 | static IntRange forValueOfCanonicalType(ASTContext &C, const Type *T) { |
9604 | isCanonicalUnqualified()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 9604, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(T->isCanonicalUnqualified()); |
9605 | |
9606 | if (const VectorType *VT = dyn_cast<VectorType>(T)) |
9607 | T = VT->getElementType().getTypePtr(); |
9608 | if (const ComplexType *CT = dyn_cast<ComplexType>(T)) |
9609 | T = CT->getElementType().getTypePtr(); |
9610 | if (const AtomicType *AT = dyn_cast<AtomicType>(T)) |
9611 | T = AT->getValueType().getTypePtr(); |
9612 | |
9613 | if (!C.getLangOpts().CPlusPlus) { |
9614 | |
9615 | if (const EnumType *ET = dyn_cast<EnumType>(T)) |
9616 | T = ET->getDecl()->getIntegerType().getDesugaredType(C).getTypePtr(); |
9617 | } else if (const EnumType *ET = dyn_cast<EnumType>(T)) { |
9618 | |
9619 | EnumDecl *Enum = ET->getDecl(); |
9620 | |
9621 | |
9622 | if (Enum->isFixed()) { |
9623 | return IntRange(C.getIntWidth(QualType(T, 0)), |
9624 | !ET->isSignedIntegerOrEnumerationType()); |
9625 | } |
9626 | |
9627 | unsigned NumPositive = Enum->getNumPositiveBits(); |
9628 | unsigned NumNegative = Enum->getNumNegativeBits(); |
9629 | |
9630 | if (NumNegative == 0) |
9631 | return IntRange(NumPositive, true); |
9632 | else |
9633 | return IntRange(std::max(NumPositive + 1, NumNegative), |
9634 | false); |
9635 | } |
9636 | |
9637 | const BuiltinType *BT = cast<BuiltinType>(T); |
9638 | isInteger()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 9638, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(BT->isInteger()); |
9639 | |
9640 | return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger()); |
9641 | } |
9642 | |
9643 | |
9644 | |
9645 | |
9646 | |
9647 | |
9648 | static IntRange forTargetOfCanonicalType(ASTContext &C, const Type *T) { |
9649 | isCanonicalUnqualified()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 9649, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(T->isCanonicalUnqualified()); |
9650 | |
9651 | if (const VectorType *VT = dyn_cast<VectorType>(T)) |
9652 | T = VT->getElementType().getTypePtr(); |
9653 | if (const ComplexType *CT = dyn_cast<ComplexType>(T)) |
9654 | T = CT->getElementType().getTypePtr(); |
9655 | if (const AtomicType *AT = dyn_cast<AtomicType>(T)) |
9656 | T = AT->getValueType().getTypePtr(); |
9657 | if (const EnumType *ET = dyn_cast<EnumType>(T)) |
9658 | T = C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr(); |
9659 | |
9660 | const BuiltinType *BT = cast<BuiltinType>(T); |
9661 | isInteger()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 9661, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(BT->isInteger()); |
9662 | |
9663 | return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger()); |
9664 | } |
9665 | |
9666 | |
9667 | static IntRange join(IntRange L, IntRange R) { |
9668 | return IntRange(std::max(L.Width, R.Width), |
9669 | L.NonNegative && R.NonNegative); |
9670 | } |
9671 | |
9672 | |
9673 | static IntRange meet(IntRange L, IntRange R) { |
9674 | return IntRange(std::min(L.Width, R.Width), |
9675 | L.NonNegative || R.NonNegative); |
9676 | } |
9677 | }; |
9678 | |
9679 | } |
9680 | |
9681 | static IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, |
9682 | unsigned MaxWidth) { |
9683 | if (value.isSigned() && value.isNegative()) |
9684 | return IntRange(value.getMinSignedBits(), false); |
9685 | |
9686 | if (value.getBitWidth() > MaxWidth) |
9687 | value = value.trunc(MaxWidth); |
9688 | |
9689 | |
9690 | |
9691 | return IntRange(value.getActiveBits(), true); |
9692 | } |
9693 | |
9694 | static IntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty, |
9695 | unsigned MaxWidth) { |
9696 | if (result.isInt()) |
9697 | return GetValueRange(C, result.getInt(), MaxWidth); |
9698 | |
9699 | if (result.isVector()) { |
9700 | IntRange R = GetValueRange(C, result.getVectorElt(0), Ty, MaxWidth); |
9701 | for (unsigned i = 1, e = result.getVectorLength(); i != e; ++i) { |
9702 | IntRange El = GetValueRange(C, result.getVectorElt(i), Ty, MaxWidth); |
9703 | R = IntRange::join(R, El); |
9704 | } |
9705 | return R; |
9706 | } |
9707 | |
9708 | if (result.isComplexInt()) { |
9709 | IntRange R = GetValueRange(C, result.getComplexIntReal(), MaxWidth); |
9710 | IntRange I = GetValueRange(C, result.getComplexIntImag(), MaxWidth); |
9711 | return IntRange::join(R, I); |
9712 | } |
9713 | |
9714 | |
9715 | |
9716 | |
9717 | |
9718 | |
9719 | assert(result.isLValue() || result.isAddrLabelDiff()); |
9720 | return IntRange(MaxWidth, Ty->isUnsignedIntegerOrEnumerationType()); |
9721 | } |
9722 | |
9723 | static QualType GetExprType(const Expr *E) { |
9724 | QualType Ty = E->getType(); |
9725 | if (const AtomicType *AtomicRHS = Ty->getAs<AtomicType>()) |
9726 | Ty = AtomicRHS->getValueType(); |
9727 | return Ty; |
9728 | } |
9729 | |
9730 | |
9731 | |
9732 | |
9733 | |
9734 | static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth) { |
9735 | E = E->IgnoreParens(); |
9736 | |
9737 | |
9738 | Expr::EvalResult result; |
9739 | if (E->EvaluateAsRValue(result, C)) |
9740 | return GetValueRange(C, result.Val, GetExprType(E), MaxWidth); |
9741 | |
9742 | |
9743 | |
9744 | |
9745 | if (const auto *CE = dyn_cast<ImplicitCastExpr>(E)) { |
9746 | if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue) |
9747 | return GetExprRange(C, CE->getSubExpr(), MaxWidth); |
9748 | |
9749 | IntRange OutputTypeRange = IntRange::forValueOfType(C, GetExprType(CE)); |
9750 | |
9751 | bool isIntegerCast = CE->getCastKind() == CK_IntegralCast || |
9752 | CE->getCastKind() == CK_BooleanToSignedIntegral; |
9753 | |
9754 | |
9755 | if (!isIntegerCast) |
9756 | return OutputTypeRange; |
9757 | |
9758 | IntRange SubRange |
9759 | = GetExprRange(C, CE->getSubExpr(), |
9760 | std::min(MaxWidth, OutputTypeRange.Width)); |
9761 | |
9762 | |
9763 | if (SubRange.Width >= OutputTypeRange.Width) |
9764 | return OutputTypeRange; |
9765 | |
9766 | |
9767 | |
9768 | return IntRange(SubRange.Width, |
9769 | SubRange.NonNegative || OutputTypeRange.NonNegative); |
9770 | } |
9771 | |
9772 | if (const auto *CO = dyn_cast<ConditionalOperator>(E)) { |
9773 | |
9774 | bool CondResult; |
9775 | if (CO->getCond()->EvaluateAsBooleanCondition(CondResult, C)) |
9776 | return GetExprRange(C, CondResult ? CO->getTrueExpr() |
9777 | : CO->getFalseExpr(), |
9778 | MaxWidth); |
9779 | |
9780 | |
9781 | IntRange L = GetExprRange(C, CO->getTrueExpr(), MaxWidth); |
9782 | IntRange R = GetExprRange(C, CO->getFalseExpr(), MaxWidth); |
9783 | return IntRange::join(L, R); |
9784 | } |
9785 | |
9786 | if (const auto *BO = dyn_cast<BinaryOperator>(E)) { |
9787 | switch (BO->getOpcode()) { |
9788 | case BO_Cmp: |
9789 | llvm_unreachable("builtin <=> should have class type"); |
9790 | |
9791 | |
9792 | case BO_LAnd: |
9793 | case BO_LOr: |
9794 | case BO_LT: |
9795 | case BO_GT: |
9796 | case BO_LE: |
9797 | case BO_GE: |
9798 | case BO_EQ: |
9799 | case BO_NE: |
9800 | return IntRange::forBoolType(); |
9801 | |
9802 | |
9803 | |
9804 | case BO_MulAssign: |
9805 | case BO_DivAssign: |
9806 | case BO_RemAssign: |
9807 | case BO_AddAssign: |
9808 | case BO_SubAssign: |
9809 | case BO_XorAssign: |
9810 | case BO_OrAssign: |
9811 | |
9812 | return IntRange::forValueOfType(C, GetExprType(E)); |
9813 | |
9814 | |
9815 | |
9816 | case BO_Assign: |
9817 | |
9818 | return GetExprRange(C, BO->getRHS(), MaxWidth); |
9819 | |
9820 | |
9821 | case BO_PtrMemD: |
9822 | case BO_PtrMemI: |
9823 | return IntRange::forValueOfType(C, GetExprType(E)); |
9824 | |
9825 | |
9826 | case BO_And: |
9827 | case BO_AndAssign: |
9828 | return IntRange::meet(GetExprRange(C, BO->getLHS(), MaxWidth), |
9829 | GetExprRange(C, BO->getRHS(), MaxWidth)); |
9830 | |
9831 | |
9832 | case BO_Shl: |
9833 | |
9834 | |
9835 | if (IntegerLiteral *I |
9836 | = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) { |
9837 | if (I->getValue() == 1) { |
9838 | IntRange R = IntRange::forValueOfType(C, GetExprType(E)); |
9839 | return IntRange(R.Width, true); |
9840 | } |
9841 | } |
9842 | LLVM_FALLTHROUGH; |
9843 | |
9844 | case BO_ShlAssign: |
9845 | return IntRange::forValueOfType(C, GetExprType(E)); |
9846 | |
9847 | |
9848 | case BO_Shr: |
9849 | case BO_ShrAssign: { |
9850 | IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth); |
9851 | |
9852 | |
9853 | |
9854 | llvm::APSInt shift; |
9855 | if (BO->getRHS()->isIntegerConstantExpr(shift, C) && |
9856 | shift.isNonNegative()) { |
9857 | unsigned zext = shift.getZExtValue(); |
9858 | if (zext >= L.Width) |
9859 | L.Width = (L.NonNegative ? 0 : 1); |
9860 | else |
9861 | L.Width -= zext; |
9862 | } |
9863 | |
9864 | return L; |
9865 | } |
9866 | |
9867 | |
9868 | case BO_Comma: |
9869 | return GetExprRange(C, BO->getRHS(), MaxWidth); |
9870 | |
9871 | |
9872 | case BO_Sub: |
9873 | if (BO->getLHS()->getType()->isPointerType()) |
9874 | return IntRange::forValueOfType(C, GetExprType(E)); |
9875 | break; |
9876 | |
9877 | |
9878 | |
9879 | case BO_Div: { |
9880 | |
9881 | unsigned opWidth = C.getIntWidth(GetExprType(E)); |
9882 | IntRange L = GetExprRange(C, BO->getLHS(), opWidth); |
9883 | |
9884 | |
9885 | llvm::APSInt divisor; |
9886 | if (BO->getRHS()->isIntegerConstantExpr(divisor, C)) { |
9887 | unsigned log2 = divisor.logBase2(); |
9888 | if (log2 >= L.Width) |
9889 | L.Width = (L.NonNegative ? 0 : 1); |
9890 | else |
9891 | L.Width = std::min(L.Width - log2, MaxWidth); |
9892 | return L; |
9893 | } |
9894 | |
9895 | |
9896 | IntRange R = GetExprRange(C, BO->getRHS(), opWidth); |
9897 | return IntRange(L.Width, L.NonNegative && R.NonNegative); |
9898 | } |
9899 | |
9900 | |
9901 | |
9902 | case BO_Rem: { |
9903 | |
9904 | unsigned opWidth = C.getIntWidth(GetExprType(E)); |
9905 | IntRange L = GetExprRange(C, BO->getLHS(), opWidth); |
9906 | IntRange R = GetExprRange(C, BO->getRHS(), opWidth); |
9907 | |
9908 | IntRange meet = IntRange::meet(L, R); |
9909 | meet.Width = std::min(meet.Width, MaxWidth); |
9910 | return meet; |
9911 | } |
9912 | |
9913 | |
9914 | case BO_Mul: |
9915 | case BO_Add: |
9916 | case BO_Xor: |
9917 | case BO_Or: |
9918 | break; |
9919 | } |
9920 | |
9921 | |
9922 | |
9923 | IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth); |
9924 | IntRange R = GetExprRange(C, BO->getRHS(), MaxWidth); |
9925 | return IntRange::join(L, R); |
9926 | } |
9927 | |
9928 | if (const auto *UO = dyn_cast<UnaryOperator>(E)) { |
9929 | switch (UO->getOpcode()) { |
9930 | |
9931 | case UO_LNot: |
9932 | return IntRange::forBoolType(); |
9933 | |
9934 | |
9935 | case UO_Deref: |
9936 | case UO_AddrOf: |
9937 | return IntRange::forValueOfType(C, GetExprType(E)); |
9938 | |
9939 | default: |
9940 | return GetExprRange(C, UO->getSubExpr(), MaxWidth); |
9941 | } |
9942 | } |
9943 | |
9944 | if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) |
9945 | return GetExprRange(C, OVE->getSourceExpr(), MaxWidth); |
9946 | |
9947 | if (const auto *BitField = E->getSourceBitField()) |
9948 | return IntRange(BitField->getBitWidthValue(C), |
9949 | BitField->getType()->isUnsignedIntegerOrEnumerationType()); |
9950 | |
9951 | return IntRange::forValueOfType(C, GetExprType(E)); |
9952 | } |
9953 | |
9954 | static IntRange GetExprRange(ASTContext &C, const Expr *E) { |
9955 | return GetExprRange(C, E, C.getIntWidth(GetExprType(E))); |
9956 | } |
9957 | |
9958 | |
9959 | |
9960 | |
9961 | static bool IsSameFloatAfterCast(const llvm::APFloat &value, |
9962 | const llvm::fltSemantics &Src, |
9963 | const llvm::fltSemantics &Tgt) { |
9964 | llvm::APFloat truncated = value; |
9965 | |
9966 | bool ignored; |
9967 | truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored); |
9968 | truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored); |
9969 | |
9970 | return truncated.bitwiseIsEqual(value); |
9971 | } |
9972 | |
9973 | |
9974 | |
9975 | |
9976 | |
9977 | |
9978 | static bool IsSameFloatAfterCast(const APValue &value, |
9979 | const llvm::fltSemantics &Src, |
9980 | const llvm::fltSemantics &Tgt) { |
9981 | if (value.isFloat()) |
9982 | return IsSameFloatAfterCast(value.getFloat(), Src, Tgt); |
9983 | |
9984 | if (value.isVector()) { |
9985 | for (unsigned i = 0, e = value.getVectorLength(); i != e; ++i) |
9986 | if (!IsSameFloatAfterCast(value.getVectorElt(i), Src, Tgt)) |
9987 | return false; |
9988 | return true; |
9989 | } |
9990 | |
9991 | assert(value.isComplexFloat()); |
9992 | return (IsSameFloatAfterCast(value.getComplexFloatReal(), Src, Tgt) && |
9993 | IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt)); |
9994 | } |
9995 | |
9996 | static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC); |
9997 | |
9998 | static bool IsEnumConstOrFromMacro(Sema &S, Expr *E) { |
9999 | |
10000 | if (const DeclRefExpr *DR = |
10001 | dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) |
10002 | if (isa<EnumConstantDecl>(DR->getDecl())) |
10003 | return true; |
10004 | |
10005 | |
10006 | if (E->getBeginLoc().isMacroID()) |
10007 | return true; |
10008 | |
10009 | return false; |
10010 | } |
10011 | |
10012 | static bool isKnownToHaveUnsignedValue(Expr *E) { |
10013 | return E->getType()->isIntegerType() && |
10014 | (!E->getType()->isSignedIntegerType() || |
10015 | !E->IgnoreParenImpCasts()->getType()->isSignedIntegerType()); |
10016 | } |
10017 | |
10018 | namespace { |
10019 | |
10020 | |
10021 | |
10022 | |
10023 | |
10024 | |
10025 | |
10026 | |
10027 | |
10028 | |
10029 | struct PromotedRange { |
10030 | |
10031 | llvm::APSInt PromotedMin; |
10032 | |
10033 | llvm::APSInt PromotedMax; |
10034 | |
10035 | PromotedRange(IntRange R, unsigned BitWidth, bool Unsigned) { |
10036 | if (R.Width == 0) |
10037 | PromotedMin = PromotedMax = llvm::APSInt(BitWidth, Unsigned); |
10038 | else if (R.Width >= BitWidth && !Unsigned) { |
10039 | |
10040 | |
10041 | |
10042 | PromotedMin = llvm::APSInt::getMinValue(BitWidth, Unsigned); |
10043 | PromotedMax = llvm::APSInt::getMaxValue(BitWidth, Unsigned); |
10044 | } else { |
10045 | PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative) |
10046 | .extOrTrunc(BitWidth); |
10047 | PromotedMin.setIsUnsigned(Unsigned); |
10048 | |
10049 | PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative) |
10050 | .extOrTrunc(BitWidth); |
10051 | PromotedMax.setIsUnsigned(Unsigned); |
10052 | } |
10053 | } |
10054 | |
10055 | |
10056 | bool isContiguous() const { return PromotedMin <= PromotedMax; } |
10057 | |
10058 | |
10059 | enum ComparisonResult { |
10060 | LT = 0x1, |
10061 | LE = 0x2, |
10062 | GT = 0x4, |
10063 | GE = 0x8, |
10064 | EQ = 0x10, |
10065 | NE = 0x20, |
10066 | InRangeFlag = 0x40, |
10067 | |
10068 | Less = LE | LT | NE, |
10069 | Min = LE | InRangeFlag, |
10070 | InRange = InRangeFlag, |
10071 | Max = GE | InRangeFlag, |
10072 | Greater = GE | GT | NE, |
10073 | |
10074 | OnlyValue = LE | GE | EQ | InRangeFlag, |
10075 | InHole = NE |
10076 | }; |
10077 | |
10078 | ComparisonResult compare(const llvm::APSInt &Value) const { |
10079 | assert(Value.getBitWidth() == PromotedMin.getBitWidth() && |
10080 | Value.isUnsigned() == PromotedMin.isUnsigned()); |
10081 | if (!isContiguous()) { |
10082 | (0) . __assert_fail ("Value.isUnsigned() && \"discontiguous range for signed compare\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 10082, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Value.isUnsigned() && "discontiguous range for signed compare"); |
10083 | if (Value.isMinValue()) return Min; |
10084 | if (Value.isMaxValue()) return Max; |
10085 | if (Value >= PromotedMin) return InRange; |
10086 | if (Value <= PromotedMax) return InRange; |
10087 | return InHole; |
10088 | } |
10089 | |
10090 | switch (llvm::APSInt::compareValues(Value, PromotedMin)) { |
10091 | case -1: return Less; |
10092 | case 0: return PromotedMin == PromotedMax ? OnlyValue : Min; |
10093 | case 1: |
10094 | switch (llvm::APSInt::compareValues(Value, PromotedMax)) { |
10095 | case -1: return InRange; |
10096 | case 0: return Max; |
10097 | case 1: return Greater; |
10098 | } |
10099 | } |
10100 | |
10101 | llvm_unreachable("impossible compare result"); |
10102 | } |
10103 | |
10104 | static llvm::Optional<StringRef> |
10105 | constantValue(BinaryOperatorKind Op, ComparisonResult R, bool ConstantOnRHS) { |
10106 | if (Op == BO_Cmp) { |
10107 | ComparisonResult LTFlag = LT, GTFlag = GT; |
10108 | if (ConstantOnRHS) std::swap(LTFlag, GTFlag); |
10109 | |
10110 | if (R & EQ) return StringRef("'std::strong_ordering::equal'"); |
10111 | if (R & LTFlag) return StringRef("'std::strong_ordering::less'"); |
10112 | if (R & GTFlag) return StringRef("'std::strong_ordering::greater'"); |
10113 | return llvm::None; |
10114 | } |
10115 | |
10116 | ComparisonResult TrueFlag, FalseFlag; |
10117 | if (Op == BO_EQ) { |
10118 | TrueFlag = EQ; |
10119 | FalseFlag = NE; |
10120 | } else if (Op == BO_NE) { |
10121 | TrueFlag = NE; |
10122 | FalseFlag = EQ; |
10123 | } else { |
10124 | if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) { |
10125 | TrueFlag = LT; |
10126 | FalseFlag = GE; |
10127 | } else { |
10128 | TrueFlag = GT; |
10129 | FalseFlag = LE; |
10130 | } |
10131 | if (Op == BO_GE || Op == BO_LE) |
10132 | std::swap(TrueFlag, FalseFlag); |
10133 | } |
10134 | if (R & TrueFlag) |
10135 | return StringRef("true"); |
10136 | if (R & FalseFlag) |
10137 | return StringRef("false"); |
10138 | return llvm::None; |
10139 | } |
10140 | }; |
10141 | } |
10142 | |
10143 | static bool HasEnumType(Expr *E) { |
10144 | |
10145 | while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { |
10146 | if (ICE->getCastKind() != CK_IntegralCast && |
10147 | ICE->getCastKind() != CK_NoOp) |
10148 | break; |
10149 | E = ICE->getSubExpr(); |
10150 | } |
10151 | |
10152 | return E->getType()->isEnumeralType(); |
10153 | } |
10154 | |
10155 | static int classifyConstantValue(Expr *Constant) { |
10156 | |
10157 | |
10158 | enum ConstantValueKind { |
10159 | Miscellaneous = 0, |
10160 | LiteralTrue, |
10161 | LiteralFalse |
10162 | }; |
10163 | if (auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant)) |
10164 | return BL->getValue() ? ConstantValueKind::LiteralTrue |
10165 | : ConstantValueKind::LiteralFalse; |
10166 | return ConstantValueKind::Miscellaneous; |
10167 | } |
10168 | |
10169 | static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, |
10170 | Expr *Constant, Expr *Other, |
10171 | const llvm::APSInt &Value, |
10172 | bool RhsConstant) { |
10173 | if (S.inTemplateInstantiation()) |
10174 | return false; |
10175 | |
10176 | Expr *OriginalOther = Other; |
10177 | |
10178 | Constant = Constant->IgnoreParenImpCasts(); |
10179 | Other = Other->IgnoreParenImpCasts(); |
10180 | |
10181 | |
10182 | |
10183 | |
10184 | |
10185 | |
10186 | |
10187 | |
10188 | if (Constant->getType()->isEnumeralType() && |
10189 | S.Context.hasSameUnqualifiedType(Constant->getType(), Other->getType())) |
10190 | return false; |
10191 | |
10192 | |
10193 | |
10194 | QualType OtherT = Other->getType(); |
10195 | if (const auto *AT = OtherT->getAs<AtomicType>()) |
10196 | OtherT = AT->getValueType(); |
10197 | IntRange OtherRange = IntRange::forValueOfType(S.Context, OtherT); |
10198 | |
10199 | |
10200 | |
10201 | bool OtherIsBooleanDespiteType = |
10202 | !OtherT->isBooleanType() && Other->isKnownToHaveBooleanValue(); |
10203 | if (OtherIsBooleanDespiteType) |
10204 | OtherRange = IntRange::forBoolType(); |
10205 | |
10206 | |
10207 | |
10208 | PromotedRange OtherPromotedRange(OtherRange, Value.getBitWidth(), |
10209 | Value.isUnsigned()); |
10210 | auto Cmp = OtherPromotedRange.compare(Value); |
10211 | auto Result = PromotedRange::constantValue(E->getOpcode(), Cmp, RhsConstant); |
10212 | if (!Result) |
10213 | return false; |
10214 | |
10215 | |
10216 | |
10217 | |
10218 | |
10219 | |
10220 | |
10221 | bool InRange = Cmp & PromotedRange::InRangeFlag; |
10222 | if (InRange && IsEnumConstOrFromMacro(S, Constant)) |
10223 | return false; |
10224 | |
10225 | |
10226 | |
10227 | const EnumConstantDecl *ED = nullptr; |
10228 | if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant)) |
10229 | ED = dyn_cast<EnumConstantDecl>(DR->getDecl()); |
10230 | |
10231 | |
10232 | SmallString<64> PrettySourceValue; |
10233 | llvm::raw_svector_ostream OS(PrettySourceValue); |
10234 | if (ED) |
10235 | OS << '\'' << *ED << "' (" << Value << ")"; |
10236 | else |
10237 | OS << Value; |
10238 | |
10239 | |
10240 | |
10241 | |
10242 | if (!InRange || Other->isKnownToHaveBooleanValue()) { |
10243 | S.DiagRuntimeBehavior( |
10244 | E->getOperatorLoc(), E, |
10245 | S.PDiag(!InRange ? diag::warn_out_of_range_compare |
10246 | : diag::warn_tautological_bool_compare) |
10247 | << OS.str() << classifyConstantValue(Constant) |
10248 | << OtherT << OtherIsBooleanDespiteType << *Result |
10249 | << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange()); |
10250 | } else { |
10251 | unsigned Diag = (isKnownToHaveUnsignedValue(OriginalOther) && Value == 0) |
10252 | ? (HasEnumType(OriginalOther) |
10253 | ? diag::warn_unsigned_enum_always_true_comparison |
10254 | : diag::warn_unsigned_always_true_comparison) |
10255 | : diag::warn_tautological_constant_compare; |
10256 | |
10257 | S.Diag(E->getOperatorLoc(), Diag) |
10258 | << RhsConstant << OtherT << E->getOpcodeStr() << OS.str() << *Result |
10259 | << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); |
10260 | } |
10261 | |
10262 | return true; |
10263 | } |
10264 | |
10265 | |
10266 | |
10267 | static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) { |
10268 | AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); |
10269 | AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); |
10270 | } |
10271 | |
10272 | |
10273 | |
10274 | |
10275 | static void AnalyzeComparison(Sema &S, BinaryOperator *E) { |
10276 | |
10277 | QualType T = E->getLHS()->getType(); |
10278 | |
10279 | |
10280 | |
10281 | if (!S.Context.hasSameUnqualifiedType(T, E->getRHS()->getType())) |
10282 | return AnalyzeImpConvsInComparison(S, E); |
10283 | |
10284 | |
10285 | if (E->isValueDependent()) |
10286 | return AnalyzeImpConvsInComparison(S, E); |
10287 | |
10288 | Expr *LHS = E->getLHS(); |
10289 | Expr *RHS = E->getRHS(); |
10290 | |
10291 | if (T->isIntegralType(S.Context)) { |
10292 | llvm::APSInt RHSValue; |
10293 | llvm::APSInt LHSValue; |
10294 | |
10295 | bool IsRHSIntegralLiteral = RHS->isIntegerConstantExpr(RHSValue, S.Context); |
10296 | bool IsLHSIntegralLiteral = LHS->isIntegerConstantExpr(LHSValue, S.Context); |
10297 | |
10298 | |
10299 | if (IsRHSIntegralLiteral && IsLHSIntegralLiteral) |
10300 | return AnalyzeImpConvsInComparison(S, E); |
10301 | |
10302 | |
10303 | if (IsRHSIntegralLiteral ^ IsLHSIntegralLiteral) { |
10304 | |
10305 | const bool RhsConstant = IsRHSIntegralLiteral; |
10306 | Expr *Const = RhsConstant ? RHS : LHS; |
10307 | Expr *Other = RhsConstant ? LHS : RHS; |
10308 | const llvm::APSInt &Value = RhsConstant ? RHSValue : LHSValue; |
10309 | |
10310 | |
10311 | |
10312 | if (CheckTautologicalComparison(S, E, Const, Other, Value, RhsConstant)) |
10313 | return AnalyzeImpConvsInComparison(S, E); |
10314 | } |
10315 | } |
10316 | |
10317 | if (!T->hasUnsignedIntegerRepresentation()) { |
10318 | |
10319 | |
10320 | |
10321 | return AnalyzeImpConvsInComparison(S, E); |
10322 | } |
10323 | |
10324 | LHS = LHS->IgnoreParenImpCasts(); |
10325 | RHS = RHS->IgnoreParenImpCasts(); |
10326 | |
10327 | if (!S.getLangOpts().CPlusPlus) { |
10328 | |
10329 | |
10330 | |
10331 | if (const auto *TET = dyn_cast<TypeOfExprType>(LHS->getType())) |
10332 | LHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts(); |
10333 | if (const auto *TET = dyn_cast<TypeOfExprType>(RHS->getType())) |
10334 | RHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts(); |
10335 | } |
10336 | |
10337 | |
10338 | |
10339 | Expr *signedOperand, *unsignedOperand; |
10340 | if (LHS->getType()->hasSignedIntegerRepresentation()) { |
10341 | (0) . __assert_fail ("!RHS->getType()->hasSignedIntegerRepresentation() && \"unsigned comparison between two signed integer expressions?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 10342, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!RHS->getType()->hasSignedIntegerRepresentation() && |
10342 | (0) . __assert_fail ("!RHS->getType()->hasSignedIntegerRepresentation() && \"unsigned comparison between two signed integer expressions?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 10342, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "unsigned comparison between two signed integer expressions?"); |
10343 | signedOperand = LHS; |
10344 | unsignedOperand = RHS; |
10345 | } else if (RHS->getType()->hasSignedIntegerRepresentation()) { |
10346 | signedOperand = RHS; |
10347 | unsignedOperand = LHS; |
10348 | } else { |
10349 | return AnalyzeImpConvsInComparison(S, E); |
10350 | } |
10351 | |
10352 | |
10353 | IntRange signedRange = GetExprRange(S.Context, signedOperand); |
10354 | |
10355 | |
10356 | |
10357 | AnalyzeImplicitConversions(S, LHS, E->getOperatorLoc()); |
10358 | AnalyzeImplicitConversions(S, RHS, E->getOperatorLoc()); |
10359 | |
10360 | |
10361 | if (signedRange.NonNegative) |
10362 | return; |
10363 | |
10364 | |
10365 | |
10366 | |
10367 | |
10368 | if (E->isEqualityOp()) { |
10369 | unsigned comparisonWidth = S.Context.getIntWidth(T); |
10370 | IntRange unsignedRange = GetExprRange(S.Context, unsignedOperand); |
10371 | |
10372 | |
10373 | |
10374 | (0) . __assert_fail ("unsignedRange.NonNegative && \"unsigned range includes negative?\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 10374, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(unsignedRange.NonNegative && "unsigned range includes negative?"); |
10375 | |
10376 | if (unsignedRange.Width < comparisonWidth) |
10377 | return; |
10378 | } |
10379 | |
10380 | S.DiagRuntimeBehavior(E->getOperatorLoc(), E, |
10381 | S.PDiag(diag::warn_mixed_sign_comparison) |
10382 | << LHS->getType() << RHS->getType() |
10383 | << LHS->getSourceRange() << RHS->getSourceRange()); |
10384 | } |
10385 | |
10386 | |
10387 | |
10388 | |
10389 | static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, |
10390 | SourceLocation InitLoc) { |
10391 | isBitField()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 10391, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Bitfield->isBitField()); |
10392 | if (Bitfield->isInvalidDecl()) |
10393 | return false; |
10394 | |
10395 | |
10396 | QualType BitfieldType = Bitfield->getType(); |
10397 | if (BitfieldType->isBooleanType()) |
10398 | return false; |
10399 | |
10400 | if (BitfieldType->isEnumeralType()) { |
10401 | EnumDecl *BitfieldEnumDecl = BitfieldType->getAs<EnumType>()->getDecl(); |
10402 | |
10403 | |
10404 | |
10405 | if (S.getLangOpts().CPlusPlus11 && |
10406 | !BitfieldEnumDecl->getIntegerTypeSourceInfo() && |
10407 | BitfieldEnumDecl->getNumPositiveBits() > 0 && |
10408 | BitfieldEnumDecl->getNumNegativeBits() == 0) { |
10409 | S.Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield) |
10410 | << BitfieldEnumDecl->getNameAsString(); |
10411 | } |
10412 | } |
10413 | |
10414 | if (Bitfield->getType()->isBooleanType()) |
10415 | return false; |
10416 | |
10417 | |
10418 | if (Bitfield->getBitWidth()->isValueDependent() || |
10419 | Bitfield->getBitWidth()->isTypeDependent() || |
10420 | Init->isValueDependent() || |
10421 | Init->isTypeDependent()) |
10422 | return false; |
10423 | |
10424 | Expr *OriginalInit = Init->IgnoreParenImpCasts(); |
10425 | unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); |
10426 | |
10427 | Expr::EvalResult Result; |
10428 | if (!OriginalInit->EvaluateAsInt(Result, S.Context, |
10429 | Expr::SE_AllowSideEffects)) { |
10430 | |
10431 | |
10432 | |
10433 | if (const auto *EnumTy = OriginalInit->getType()->getAs<EnumType>()) { |
10434 | EnumDecl *ED = EnumTy->getDecl(); |
10435 | bool SignedBitfield = BitfieldType->isSignedIntegerType(); |
10436 | |
10437 | |
10438 | |
10439 | |
10440 | bool SignedEnum = ED->getNumNegativeBits() > 0; |
10441 | |
10442 | |
10443 | |
10444 | |
10445 | |
10446 | |
10447 | unsigned DiagID = 0; |
10448 | if (SignedEnum && !SignedBitfield) { |
10449 | DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum; |
10450 | } else if (SignedBitfield && !SignedEnum && |
10451 | ED->getNumPositiveBits() == FieldWidth) { |
10452 | DiagID = diag::warn_signed_bitfield_enum_conversion; |
10453 | } |
10454 | |
10455 | if (DiagID) { |
10456 | S.Diag(InitLoc, DiagID) << Bitfield << ED; |
10457 | TypeSourceInfo *TSI = Bitfield->getTypeSourceInfo(); |
10458 | SourceRange TypeRange = |
10459 | TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange(); |
10460 | S.Diag(Bitfield->getTypeSpecStartLoc(), diag::note_change_bitfield_sign) |
10461 | << SignedEnum << TypeRange; |
10462 | } |
10463 | |
10464 | |
10465 | |
10466 | |
10467 | unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1, |
10468 | ED->getNumNegativeBits()) |
10469 | : ED->getNumPositiveBits(); |
10470 | |
10471 | |
10472 | if (BitsNeeded > FieldWidth) { |
10473 | Expr *WidthExpr = Bitfield->getBitWidth(); |
10474 | S.Diag(InitLoc, diag::warn_bitfield_too_small_for_enum) |
10475 | << Bitfield << ED; |
10476 | S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield) |
10477 | << BitsNeeded << ED << WidthExpr->getSourceRange(); |
10478 | } |
10479 | } |
10480 | |
10481 | return false; |
10482 | } |
10483 | |
10484 | llvm::APSInt Value = Result.Val.getInt(); |
10485 | |
10486 | unsigned OriginalWidth = Value.getBitWidth(); |
10487 | |
10488 | if (!Value.isSigned() || Value.isNegative()) |
10489 | if (UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit)) |
10490 | if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not) |
10491 | OriginalWidth = Value.getMinSignedBits(); |
10492 | |
10493 | if (OriginalWidth <= FieldWidth) |
10494 | return false; |
10495 | |
10496 | |
10497 | llvm::APSInt TruncatedValue = Value.trunc(FieldWidth); |
10498 | TruncatedValue.setIsSigned(BitfieldType->isSignedIntegerType()); |
10499 | |
10500 | |
10501 | TruncatedValue = TruncatedValue.extend(OriginalWidth); |
10502 | if (llvm::APSInt::isSameValue(Value, TruncatedValue)) |
10503 | return false; |
10504 | |
10505 | |
10506 | |
10507 | if (FieldWidth == 1 && Value == 1) |
10508 | return false; |
10509 | |
10510 | std::string PrettyValue = Value.toString(10); |
10511 | std::string PrettyTrunc = TruncatedValue.toString(10); |
10512 | |
10513 | S.Diag(InitLoc, diag::warn_impcast_bitfield_precision_constant) |
10514 | << PrettyValue << PrettyTrunc << OriginalInit->getType() |
10515 | << Init->getSourceRange(); |
10516 | |
10517 | return true; |
10518 | } |
10519 | |
10520 | |
10521 | |
10522 | static void AnalyzeAssignment(Sema &S, BinaryOperator *E) { |
10523 | |
10524 | AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); |
10525 | |
10526 | |
10527 | |
10528 | if (FieldDecl *Bitfield = E->getLHS()->getSourceBitField()) { |
10529 | if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(), |
10530 | E->getOperatorLoc())) { |
10531 | |
10532 | return AnalyzeImplicitConversions(S, E->getRHS()->IgnoreParenImpCasts(), |
10533 | E->getOperatorLoc()); |
10534 | } |
10535 | } |
10536 | |
10537 | AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); |
10538 | |
10539 | |
10540 | if (E->getLHS()->getType()->isAtomicType()) |
10541 | S.Diag(E->getRHS()->getBeginLoc(), diag::warn_atomic_implicit_seq_cst); |
10542 | } |
10543 | |
10544 | |
10545 | static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, |
10546 | SourceLocation CContext, unsigned diag, |
10547 | bool pruneControlFlow = false) { |
10548 | if (pruneControlFlow) { |
10549 | S.DiagRuntimeBehavior(E->getExprLoc(), E, |
10550 | S.PDiag(diag) |
10551 | << SourceType << T << E->getSourceRange() |
10552 | << SourceRange(CContext)); |
10553 | return; |
10554 | } |
10555 | S.Diag(E->getExprLoc(), diag) |
10556 | << SourceType << T << E->getSourceRange() << SourceRange(CContext); |
10557 | } |
10558 | |
10559 | |
10560 | static void DiagnoseImpCast(Sema &S, Expr *E, QualType T, |
10561 | SourceLocation CContext, |
10562 | unsigned diag, bool pruneControlFlow = false) { |
10563 | DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow); |
10564 | } |
10565 | |
10566 | |
10567 | static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, |
10568 | SourceLocation CContext) { |
10569 | const bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool); |
10570 | const bool PruneWarnings = S.inTemplateInstantiation(); |
10571 | |
10572 | Expr *InnerE = E->IgnoreParenImpCasts(); |
10573 | |
10574 | if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(InnerE)) |
10575 | if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus) |
10576 | InnerE = UOp->getSubExpr()->IgnoreParenImpCasts(); |
10577 | |
10578 | const bool IsLiteral = |
10579 | isa<FloatingLiteral>(E) || isa<FloatingLiteral>(InnerE); |
10580 | |
10581 | llvm::APFloat Value(0.0); |
10582 | bool IsConstant = |
10583 | E->EvaluateAsFloat(Value, S.Context, Expr::SE_AllowSideEffects); |
10584 | if (!IsConstant) { |
10585 | return DiagnoseImpCast(S, E, T, CContext, |
10586 | diag::warn_impcast_float_integer, PruneWarnings); |
10587 | } |
10588 | |
10589 | bool isExact = false; |
10590 | |
10591 | llvm::APSInt IntegerValue(S.Context.getIntWidth(T), |
10592 | T->hasUnsignedIntegerRepresentation()); |
10593 | llvm::APFloat::opStatus Result = Value.convertToInteger( |
10594 | IntegerValue, llvm::APFloat::rmTowardZero, &isExact); |
10595 | |
10596 | if (Result == llvm::APFloat::opOK && isExact) { |
10597 | if (IsLiteral) return; |
10598 | return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer, |
10599 | PruneWarnings); |
10600 | } |
10601 | |
10602 | |
10603 | |
10604 | if (!IsBool && Result == llvm::APFloat::opInvalidOp) |
10605 | return DiagnoseImpCast( |
10606 | S, E, T, CContext, |
10607 | IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range |
10608 | : diag::warn_impcast_float_to_integer_out_of_range, |
10609 | PruneWarnings); |
10610 | |
10611 | unsigned DiagID = 0; |
10612 | if (IsLiteral) { |
10613 | |
10614 | DiagID = diag::warn_impcast_literal_float_to_integer; |
10615 | } else if (IntegerValue == 0) { |
10616 | if (Value.isZero()) { |
10617 | return DiagnoseImpCast(S, E, T, CContext, |
10618 | diag::warn_impcast_float_integer, PruneWarnings); |
10619 | } |
10620 | |
10621 | DiagID = diag::warn_impcast_float_to_integer_zero; |
10622 | } else { |
10623 | if (IntegerValue.isUnsigned()) { |
10624 | if (!IntegerValue.isMaxValue()) { |
10625 | return DiagnoseImpCast(S, E, T, CContext, |
10626 | diag::warn_impcast_float_integer, PruneWarnings); |
10627 | } |
10628 | } else { |
10629 | if (!IntegerValue.isMaxSignedValue() && |
10630 | !IntegerValue.isMinSignedValue()) { |
10631 | return DiagnoseImpCast(S, E, T, CContext, |
10632 | diag::warn_impcast_float_integer, PruneWarnings); |
10633 | } |
10634 | } |
10635 | |
10636 | DiagID = diag::warn_impcast_float_to_integer; |
10637 | } |
10638 | |
10639 | |
10640 | |
10641 | |
10642 | |
10643 | |
10644 | SmallString<16> PrettySourceValue; |
10645 | unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics()); |
10646 | precision = (precision * 59 + 195) / 196; |
10647 | Value.toString(PrettySourceValue, precision); |
10648 | |
10649 | SmallString<16> PrettyTargetValue; |
10650 | if (IsBool) |
10651 | PrettyTargetValue = Value.isZero() ? "false" : "true"; |
10652 | else |
10653 | IntegerValue.toString(PrettyTargetValue); |
10654 | |
10655 | if (PruneWarnings) { |
10656 | S.DiagRuntimeBehavior(E->getExprLoc(), E, |
10657 | S.PDiag(DiagID) |
10658 | << E->getType() << T.getUnqualifiedType() |
10659 | << PrettySourceValue << PrettyTargetValue |
10660 | << E->getSourceRange() << SourceRange(CContext)); |
10661 | } else { |
10662 | S.Diag(E->getExprLoc(), DiagID) |
10663 | << E->getType() << T.getUnqualifiedType() << PrettySourceValue |
10664 | << PrettyTargetValue << E->getSourceRange() << SourceRange(CContext); |
10665 | } |
10666 | } |
10667 | |
10668 | |
10669 | |
10670 | static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) { |
10671 | (0) . __assert_fail ("isa(E) && \"Must be compound assignment operation\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 10672, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CompoundAssignOperator>(E) && |
10672 | (0) . __assert_fail ("isa(E) && \"Must be compound assignment operation\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 10672, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Must be compound assignment operation"); |
10673 | |
10674 | AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); |
10675 | AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); |
10676 | |
10677 | if (E->getLHS()->getType()->isAtomicType()) |
10678 | S.Diag(E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst); |
10679 | |
10680 | |
10681 | const auto *ResultBT = E->getLHS()->getType()->getAs<BuiltinType>(); |
10682 | const auto *RBT = cast<CompoundAssignOperator>(E) |
10683 | ->getComputationResultType() |
10684 | ->getAs<BuiltinType>(); |
10685 | |
10686 | |
10687 | if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return; |
10688 | |
10689 | |
10690 | if (ResultBT->isInteger()) |
10691 | return DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(), |
10692 | E->getExprLoc(), diag::warn_impcast_float_integer); |
10693 | |
10694 | if (!ResultBT->isFloatingPoint()) |
10695 | return; |
10696 | |
10697 | |
10698 | int Order = S.getASTContext().getFloatingTypeSemanticOrder( |
10699 | QualType(ResultBT, 0), QualType(RBT, 0)); |
10700 | if (Order < 0 && !S.SourceMgr.isInSystemMacro(E->getOperatorLoc())) |
10701 | |
10702 | DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(), |
10703 | diag::warn_impcast_float_result_precision); |
10704 | } |
10705 | |
10706 | static std::string PrettyPrintInRange(const llvm::APSInt &Value, |
10707 | IntRange Range) { |
10708 | if (!Range.Width) return "0"; |
10709 | |
10710 | llvm::APSInt ValueInRange = Value; |
10711 | ValueInRange.setIsSigned(!Range.NonNegative); |
10712 | ValueInRange = ValueInRange.trunc(Range.Width); |
10713 | return ValueInRange.toString(10); |
10714 | } |
10715 | |
10716 | static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool) { |
10717 | if (!isa<ImplicitCastExpr>(Ex)) |
10718 | return false; |
10719 | |
10720 | Expr *InnerE = Ex->IgnoreParenImpCasts(); |
10721 | const Type *Target = S.Context.getCanonicalType(Ex->getType()).getTypePtr(); |
10722 | const Type *Source = |
10723 | S.Context.getCanonicalType(InnerE->getType()).getTypePtr(); |
10724 | if (Target->isDependentType()) |
10725 | return false; |
10726 | |
10727 | const BuiltinType *FloatCandidateBT = |
10728 | dyn_cast<BuiltinType>(ToBool ? Source : Target); |
10729 | const Type *BoolCandidateType = ToBool ? Target : Source; |
10730 | |
10731 | return (BoolCandidateType->isSpecificBuiltinType(BuiltinType::Bool) && |
10732 | FloatCandidateBT && (FloatCandidateBT->isFloatingPoint())); |
10733 | } |
10734 | |
10735 | static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, |
10736 | SourceLocation CC) { |
10737 | unsigned NumArgs = TheCall->getNumArgs(); |
10738 | for (unsigned i = 0; i < NumArgs; ++i) { |
10739 | Expr *CurrA = TheCall->getArg(i); |
10740 | if (!IsImplicitBoolFloatConversion(S, CurrA, true)) |
10741 | continue; |
10742 | |
10743 | bool IsSwapped = ((i > 0) && |
10744 | IsImplicitBoolFloatConversion(S, TheCall->getArg(i - 1), false)); |
10745 | IsSwapped |= ((i < (NumArgs - 1)) && |
10746 | IsImplicitBoolFloatConversion(S, TheCall->getArg(i + 1), false)); |
10747 | if (IsSwapped) { |
10748 | |
10749 | DiagnoseImpCast(S, CurrA->IgnoreParenImpCasts(), |
10750 | CurrA->getType(), CC, |
10751 | diag::warn_impcast_floating_point_to_bool); |
10752 | } |
10753 | } |
10754 | } |
10755 | |
10756 | static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, |
10757 | SourceLocation CC) { |
10758 | if (S.Diags.isIgnored(diag::warn_impcast_null_pointer_to_integer, |
10759 | E->getExprLoc())) |
10760 | return; |
10761 | |
10762 | |
10763 | if (isa<CallExpr>(E)) |
10764 | return; |
10765 | |
10766 | |
10767 | const Expr::NullPointerConstantKind NullKind = |
10768 | E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull); |
10769 | if (NullKind != Expr::NPCK_GNUNull && NullKind != Expr::NPCK_CXX11_nullptr) |
10770 | return; |
10771 | |
10772 | |
10773 | if (T->isAnyPointerType() || T->isBlockPointerType() || |
10774 | T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType()) |
10775 | return; |
10776 | |
10777 | SourceLocation Loc = E->getSourceRange().getBegin(); |
10778 | |
10779 | |
10780 | |
10781 | |
10782 | Loc = S.SourceMgr.getTopMacroCallerLoc(Loc); |
10783 | CC = S.SourceMgr.getTopMacroCallerLoc(CC); |
10784 | |
10785 | |
10786 | if (NullKind == Expr::NPCK_GNUNull && Loc.isMacroID()) { |
10787 | StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics( |
10788 | Loc, S.SourceMgr, S.getLangOpts()); |
10789 | if (MacroName == "NULL") |
10790 | Loc = S.SourceMgr.getImmediateExpansionRange(Loc).getBegin(); |
10791 | } |
10792 | |
10793 | |
10794 | if (S.SourceMgr.getFileID(Loc) != S.SourceMgr.getFileID(CC)) |
10795 | return; |
10796 | |
10797 | S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) |
10798 | << (NullKind == Expr::NPCK_CXX11_nullptr) << T << SourceRange(CC) |
10799 | << FixItHint::CreateReplacement(Loc, |
10800 | S.getFixItZeroLiteralForType(T, Loc)); |
10801 | } |
10802 | |
10803 | static void checkObjCArrayLiteral(Sema &S, QualType TargetType, |
10804 | ObjCArrayLiteral *ArrayLiteral); |
10805 | |
10806 | static void |
10807 | checkObjCDictionaryLiteral(Sema &S, QualType TargetType, |
10808 | ObjCDictionaryLiteral *DictionaryLiteral); |
10809 | |
10810 | |
10811 | |
10812 | static void checkObjCCollectionLiteralElement(Sema &S, |
10813 | QualType TargetElementType, |
10814 | Expr *Element, |
10815 | unsigned ElementKind) { |
10816 | |
10817 | if (auto ICE = dyn_cast<ImplicitCastExpr>(Element)) { |
10818 | if (ICE->getCastKind() == CK_BitCast && |
10819 | ICE->getSubExpr()->getType()->getAs<ObjCObjectPointerType>()) |
10820 | Element = ICE->getSubExpr(); |
10821 | } |
10822 | |
10823 | QualType ElementType = Element->getType(); |
10824 | ExprResult ElementResult(Element); |
10825 | if (ElementType->getAs<ObjCObjectPointerType>() && |
10826 | S.CheckSingleAssignmentConstraints(TargetElementType, |
10827 | ElementResult, |
10828 | false, false) |
10829 | != Sema::Compatible) { |
10830 | S.Diag(Element->getBeginLoc(), diag::warn_objc_collection_literal_element) |
10831 | << ElementType << ElementKind << TargetElementType |
10832 | << Element->getSourceRange(); |
10833 | } |
10834 | |
10835 | if (auto ArrayLiteral = dyn_cast<ObjCArrayLiteral>(Element)) |
10836 | checkObjCArrayLiteral(S, TargetElementType, ArrayLiteral); |
10837 | else if (auto DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(Element)) |
10838 | checkObjCDictionaryLiteral(S, TargetElementType, DictionaryLiteral); |
10839 | } |
10840 | |
10841 | |
10842 | |
10843 | static void checkObjCArrayLiteral(Sema &S, QualType TargetType, |
10844 | ObjCArrayLiteral *ArrayLiteral) { |
10845 | if (!S.NSArrayDecl) |
10846 | return; |
10847 | |
10848 | const auto *TargetObjCPtr = TargetType->getAs<ObjCObjectPointerType>(); |
10849 | if (!TargetObjCPtr) |
10850 | return; |
10851 | |
10852 | if (TargetObjCPtr->isUnspecialized() || |
10853 | TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() |
10854 | != S.NSArrayDecl->getCanonicalDecl()) |
10855 | return; |
10856 | |
10857 | auto TypeArgs = TargetObjCPtr->getTypeArgs(); |
10858 | if (TypeArgs.size() != 1) |
10859 | return; |
10860 | |
10861 | QualType TargetElementType = TypeArgs[0]; |
10862 | for (unsigned I = 0, N = ArrayLiteral->getNumElements(); I != N; ++I) { |
10863 | checkObjCCollectionLiteralElement(S, TargetElementType, |
10864 | ArrayLiteral->getElement(I), |
10865 | 0); |
10866 | } |
10867 | } |
10868 | |
10869 | |
10870 | |
10871 | static void |
10872 | checkObjCDictionaryLiteral(Sema &S, QualType TargetType, |
10873 | ObjCDictionaryLiteral *DictionaryLiteral) { |
10874 | if (!S.NSDictionaryDecl) |
10875 | return; |
10876 | |
10877 | const auto *TargetObjCPtr = TargetType->getAs<ObjCObjectPointerType>(); |
10878 | if (!TargetObjCPtr) |
10879 | return; |
10880 | |
10881 | if (TargetObjCPtr->isUnspecialized() || |
10882 | TargetObjCPtr->getInterfaceDecl()->getCanonicalDecl() |
10883 | != S.NSDictionaryDecl->getCanonicalDecl()) |
10884 | return; |
10885 | |
10886 | auto TypeArgs = TargetObjCPtr->getTypeArgs(); |
10887 | if (TypeArgs.size() != 2) |
10888 | return; |
10889 | |
10890 | QualType TargetKeyType = TypeArgs[0]; |
10891 | QualType TargetObjectType = TypeArgs[1]; |
10892 | for (unsigned I = 0, N = DictionaryLiteral->getNumElements(); I != N; ++I) { |
10893 | auto Element = DictionaryLiteral->getKeyValueElement(I); |
10894 | checkObjCCollectionLiteralElement(S, TargetKeyType, Element.Key, 1); |
10895 | checkObjCCollectionLiteralElement(S, TargetObjectType, Element.Value, 2); |
10896 | } |
10897 | } |
10898 | |
10899 | |
10900 | |
10901 | static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, |
10902 | SourceLocation CC) { |
10903 | |
10904 | |
10905 | |
10906 | if (auto *IntLit = dyn_cast<IntegerLiteral>(E->IgnoreParenImpCasts())) { |
10907 | const char FirstLiteralCharacter = |
10908 | S.getSourceManager().getCharacterData(IntLit->getBeginLoc())[0]; |
10909 | if (FirstLiteralCharacter == '0') |
10910 | return false; |
10911 | } |
10912 | |
10913 | |
10914 | |
10915 | if (CC.isValid() && T->isCharType()) { |
10916 | const char FirstContextCharacter = |
10917 | S.getSourceManager().getCharacterData(CC)[0]; |
10918 | if (FirstContextCharacter == '{') |
10919 | return false; |
10920 | } |
10921 | |
10922 | return true; |
10923 | } |
10924 | |
10925 | static void |
10926 | CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, |
10927 | bool *ICContext = nullptr) { |
10928 | if (E->isTypeDependent() || E->isValueDependent()) return; |
10929 | |
10930 | const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr(); |
10931 | const Type *Target = S.Context.getCanonicalType(T).getTypePtr(); |
10932 | if (Source == Target) return; |
10933 | if (Target->isDependentType()) return; |
10934 | |
10935 | |
10936 | |
10937 | |
10938 | |
10939 | |
10940 | if (CC.isInvalid()) |
10941 | return; |
10942 | |
10943 | if (Source->isAtomicType()) |
10944 | S.Diag(E->getExprLoc(), diag::warn_atomic_implicit_seq_cst); |
10945 | |
10946 | |
10947 | if (Target->isSpecificBuiltinType(BuiltinType::Bool)) { |
10948 | if (isa<StringLiteral>(E)) |
10949 | |
10950 | |
10951 | |
10952 | return DiagnoseImpCast(S, E, T, CC, |
10953 | diag::warn_impcast_string_literal_to_bool); |
10954 | if (isa<ObjCStringLiteral>(E) || isa<ObjCArrayLiteral>(E) || |
10955 | isa<ObjCDictionaryLiteral>(E) || isa<ObjCBoxedExpr>(E)) { |
10956 | |
10957 | |
10958 | return DiagnoseImpCast(S, E, T, CC, |
10959 | diag::warn_impcast_objective_c_literal_to_bool); |
10960 | } |
10961 | if (Source->isPointerType() || Source->canDecayToPointerType()) { |
10962 | |
10963 | S.DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, false, |
10964 | SourceRange(CC)); |
10965 | } |
10966 | } |
10967 | |
10968 | |
10969 | |
10970 | if (auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E)) |
10971 | checkObjCArrayLiteral(S, QualType(Target, 0), ArrayLiteral); |
10972 | else if (auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E)) |
10973 | checkObjCDictionaryLiteral(S, QualType(Target, 0), DictionaryLiteral); |
10974 | |
10975 | |
10976 | if (isa<VectorType>(Source)) { |
10977 | if (!isa<VectorType>(Target)) { |
10978 | if (S.SourceMgr.isInSystemMacro(CC)) |
10979 | return; |
10980 | return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_vector_scalar); |
10981 | } |
10982 | |
10983 | |
10984 | |
10985 | if (S.Context.getTypeSize(Source) == S.Context.getTypeSize(Target)) |
10986 | return; |
10987 | |
10988 | Source = cast<VectorType>(Source)->getElementType().getTypePtr(); |
10989 | Target = cast<VectorType>(Target)->getElementType().getTypePtr(); |
10990 | } |
10991 | if (auto VecTy = dyn_cast<VectorType>(Target)) |
10992 | Target = VecTy->getElementType().getTypePtr(); |
10993 | |
10994 | |
10995 | if (isa<ComplexType>(Source)) { |
10996 | if (!isa<ComplexType>(Target)) { |
10997 | if (S.SourceMgr.isInSystemMacro(CC) || Target->isBooleanType()) |
10998 | return; |
10999 | |
11000 | return DiagnoseImpCast(S, E, T, CC, |
11001 | S.getLangOpts().CPlusPlus |
11002 | ? diag::err_impcast_complex_scalar |
11003 | : diag::warn_impcast_complex_scalar); |
11004 | } |
11005 | |
11006 | Source = cast<ComplexType>(Source)->getElementType().getTypePtr(); |
11007 | Target = cast<ComplexType>(Target)->getElementType().getTypePtr(); |
11008 | } |
11009 | |
11010 | const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source); |
11011 | const BuiltinType *TargetBT = dyn_cast<BuiltinType>(Target); |
11012 | |
11013 | |
11014 | if (SourceBT && SourceBT->isFloatingPoint()) { |
11015 | |
11016 | if (TargetBT && TargetBT->isFloatingPoint()) { |
11017 | |
11018 | |
11019 | int Order = S.getASTContext().getFloatingTypeSemanticOrder( |
11020 | QualType(SourceBT, 0), QualType(TargetBT, 0)); |
11021 | if (Order > 0) { |
11022 | |
11023 | |
11024 | Expr::EvalResult result; |
11025 | if (E->EvaluateAsRValue(result, S.Context)) { |
11026 | |
11027 | if (IsSameFloatAfterCast(result.Val, |
11028 | S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)), |
11029 | S.Context.getFloatTypeSemantics(QualType(SourceBT, 0)))) |
11030 | return; |
11031 | } |
11032 | |
11033 | if (S.SourceMgr.isInSystemMacro(CC)) |
11034 | return; |
11035 | |
11036 | DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_precision); |
11037 | } |
11038 | |
11039 | else if (Order < 0) { |
11040 | if (S.SourceMgr.isInSystemMacro(CC)) |
11041 | return; |
11042 | |
11043 | DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_double_promotion); |
11044 | } |
11045 | return; |
11046 | } |
11047 | |
11048 | |
11049 | if (TargetBT && TargetBT->isInteger()) { |
11050 | if (S.SourceMgr.isInSystemMacro(CC)) |
11051 | return; |
11052 | |
11053 | DiagnoseFloatingImpCast(S, E, T, CC); |
11054 | } |
11055 | |
11056 | |
11057 | |
11058 | |
11059 | |
11060 | |
11061 | |
11062 | |
11063 | |
11064 | if (Target->isBooleanType() && isa<CallExpr>(E)) { |
11065 | |
11066 | |
11067 | |
11068 | CallExpr *CEx = cast<CallExpr>(E); |
11069 | if (unsigned NumArgs = CEx->getNumArgs()) { |
11070 | Expr *LastA = CEx->getArg(NumArgs - 1); |
11071 | Expr *InnerE = LastA->IgnoreParenImpCasts(); |
11072 | if (isa<ImplicitCastExpr>(LastA) && |
11073 | InnerE->getType()->isBooleanType()) { |
11074 | |
11075 | DiagnoseImpCast(S, E, T, CC, |
11076 | diag::warn_impcast_floating_point_to_bool); |
11077 | } |
11078 | } |
11079 | } |
11080 | return; |
11081 | } |
11082 | |
11083 | |
11084 | if (Source->isFixedPointType()) { |
11085 | if (Target->isUnsaturatedFixedPointType()) { |
11086 | Expr::EvalResult Result; |
11087 | if (E->EvaluateAsFixedPoint(Result, S.Context, |
11088 | Expr::SE_AllowSideEffects)) { |
11089 | APFixedPoint Value = Result.Val.getFixedPoint(); |
11090 | APFixedPoint MaxVal = S.Context.getFixedPointMax(T); |
11091 | APFixedPoint MinVal = S.Context.getFixedPointMin(T); |
11092 | if (Value > MaxVal || Value < MinVal) { |
11093 | S.DiagRuntimeBehavior(E->getExprLoc(), E, |
11094 | S.PDiag(diag::warn_impcast_fixed_point_range) |
11095 | << Value.toString() << T |
11096 | << E->getSourceRange() |
11097 | << clang::SourceRange(CC)); |
11098 | return; |
11099 | } |
11100 | } |
11101 | } else if (Target->isIntegerType()) { |
11102 | Expr::EvalResult Result; |
11103 | if (E->EvaluateAsFixedPoint(Result, S.Context, |
11104 | Expr::SE_AllowSideEffects)) { |
11105 | APFixedPoint FXResult = Result.Val.getFixedPoint(); |
11106 | |
11107 | bool Overflowed; |
11108 | llvm::APSInt IntResult = FXResult.convertToInt( |
11109 | S.Context.getIntWidth(T), |
11110 | Target->isSignedIntegerOrEnumerationType(), &Overflowed); |
11111 | |
11112 | if (Overflowed) { |
11113 | S.DiagRuntimeBehavior(E->getExprLoc(), E, |
11114 | S.PDiag(diag::warn_impcast_fixed_point_range) |
11115 | << FXResult.toString() << T |
11116 | << E->getSourceRange() |
11117 | << clang::SourceRange(CC)); |
11118 | return; |
11119 | } |
11120 | } |
11121 | } |
11122 | } else if (Target->isUnsaturatedFixedPointType()) { |
11123 | if (Source->isIntegerType()) { |
11124 | Expr::EvalResult Result; |
11125 | if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) { |
11126 | llvm::APSInt Value = Result.Val.getInt(); |
11127 | |
11128 | bool Overflowed; |
11129 | APFixedPoint IntResult = APFixedPoint::getFromIntValue( |
11130 | Value, S.Context.getFixedPointSemantics(T), &Overflowed); |
11131 | |
11132 | if (Overflowed) { |
11133 | S.DiagRuntimeBehavior(E->getExprLoc(), E, |
11134 | S.PDiag(diag::warn_impcast_fixed_point_range) |
11135 | << Value.toString() << T |
11136 | << E->getSourceRange() |
11137 | << clang::SourceRange(CC)); |
11138 | return; |
11139 | } |
11140 | } |
11141 | } |
11142 | } |
11143 | |
11144 | DiagnoseNullConversion(S, E, T, CC); |
11145 | |
11146 | S.DiscardMisalignedMemberAddress(Target, E); |
11147 | |
11148 | if (!Source->isIntegerType() || !Target->isIntegerType()) |
11149 | return; |
11150 | |
11151 | |
11152 | |
11153 | if (Target->isSpecificBuiltinType(BuiltinType::Bool)) |
11154 | return; |
11155 | |
11156 | IntRange SourceRange = GetExprRange(S.Context, E); |
11157 | IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target); |
11158 | |
11159 | if (SourceRange.Width > TargetRange.Width) { |
11160 | |
11161 | |
11162 | Expr::EvalResult Result; |
11163 | if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) { |
11164 | llvm::APSInt Value(32); |
11165 | Value = Result.Val.getInt(); |
11166 | |
11167 | if (S.SourceMgr.isInSystemMacro(CC)) |
11168 | return; |
11169 | |
11170 | std::string PrettySourceValue = Value.toString(10); |
11171 | std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange); |
11172 | |
11173 | S.DiagRuntimeBehavior(E->getExprLoc(), E, |
11174 | S.PDiag(diag::warn_impcast_integer_precision_constant) |
11175 | << PrettySourceValue << PrettyTargetValue |
11176 | << E->getType() << T << E->getSourceRange() |
11177 | << clang::SourceRange(CC)); |
11178 | return; |
11179 | } |
11180 | |
11181 | |
11182 | if (S.SourceMgr.isInSystemMacro(CC)) |
11183 | return; |
11184 | |
11185 | if (TargetRange.Width == 32 && S.Context.getIntWidth(E->getType()) == 64) |
11186 | return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_64_32, |
11187 | true); |
11188 | return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision); |
11189 | } |
11190 | |
11191 | if (TargetRange.Width > SourceRange.Width) { |
11192 | if (auto *UO = dyn_cast<UnaryOperator>(E)) |
11193 | if (UO->getOpcode() == UO_Minus) |
11194 | if (Source->isUnsignedIntegerType()) { |
11195 | if (Target->isUnsignedIntegerType()) |
11196 | return DiagnoseImpCast(S, E, T, CC, |
11197 | diag::warn_impcast_high_order_zero_bits); |
11198 | if (Target->isSignedIntegerType()) |
11199 | return DiagnoseImpCast(S, E, T, CC, |
11200 | diag::warn_impcast_nonnegative_result); |
11201 | } |
11202 | } |
11203 | |
11204 | if (TargetRange.Width == SourceRange.Width && !TargetRange.NonNegative && |
11205 | SourceRange.NonNegative && Source->isSignedIntegerType()) { |
11206 | |
11207 | |
11208 | |
11209 | |
11210 | Expr::EvalResult Result; |
11211 | if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects) && |
11212 | !S.SourceMgr.isInSystemMacro(CC)) { |
11213 | llvm::APSInt Value = Result.Val.getInt(); |
11214 | if (isSameWidthConstantConversion(S, E, T, CC)) { |
11215 | std::string PrettySourceValue = Value.toString(10); |
11216 | std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange); |
11217 | |
11218 | S.DiagRuntimeBehavior( |
11219 | E->getExprLoc(), E, |
11220 | S.PDiag(diag::warn_impcast_integer_precision_constant) |
11221 | << PrettySourceValue << PrettyTargetValue << E->getType() << T |
11222 | << E->getSourceRange() << clang::SourceRange(CC)); |
11223 | return; |
11224 | } |
11225 | } |
11226 | |
11227 | |
11228 | } |
11229 | |
11230 | if ((TargetRange.NonNegative && !SourceRange.NonNegative) || |
11231 | (!TargetRange.NonNegative && SourceRange.NonNegative && |
11232 | SourceRange.Width == TargetRange.Width)) { |
11233 | if (S.SourceMgr.isInSystemMacro(CC)) |
11234 | return; |
11235 | |
11236 | unsigned DiagID = diag::warn_impcast_integer_sign; |
11237 | |
11238 | |
11239 | |
11240 | |
11241 | |
11242 | |
11243 | if (ICContext) { |
11244 | DiagID = diag::warn_impcast_integer_sign_conditional; |
11245 | *ICContext = true; |
11246 | } |
11247 | |
11248 | return DiagnoseImpCast(S, E, T, CC, DiagID); |
11249 | } |
11250 | |
11251 | |
11252 | |
11253 | |
11254 | QualType SourceType = E->getType(); |
11255 | if (!S.getLangOpts().CPlusPlus) { |
11256 | if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) |
11257 | if (EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { |
11258 | EnumDecl *Enum = cast<EnumDecl>(ECD->getDeclContext()); |
11259 | SourceType = S.Context.getTypeDeclType(Enum); |
11260 | Source = S.Context.getCanonicalType(SourceType).getTypePtr(); |
11261 | } |
11262 | } |
11263 | |
11264 | if (const EnumType *SourceEnum = Source->getAs<EnumType>()) |
11265 | if (const EnumType *TargetEnum = Target->getAs<EnumType>()) |
11266 | if (SourceEnum->getDecl()->hasNameForLinkage() && |
11267 | TargetEnum->getDecl()->hasNameForLinkage() && |
11268 | SourceEnum != TargetEnum) { |
11269 | if (S.SourceMgr.isInSystemMacro(CC)) |
11270 | return; |
11271 | |
11272 | return DiagnoseImpCast(S, E, SourceType, T, CC, |
11273 | diag::warn_impcast_different_enum_types); |
11274 | } |
11275 | } |
11276 | |
11277 | static void CheckConditionalOperator(Sema &S, ConditionalOperator *E, |
11278 | SourceLocation CC, QualType T); |
11279 | |
11280 | static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, |
11281 | SourceLocation CC, bool &ICContext) { |
11282 | E = E->IgnoreParenImpCasts(); |
11283 | |
11284 | if (isa<ConditionalOperator>(E)) |
11285 | return CheckConditionalOperator(S, cast<ConditionalOperator>(E), CC, T); |
11286 | |
11287 | AnalyzeImplicitConversions(S, E, CC); |
11288 | if (E->getType() != T) |
11289 | return CheckImplicitConversion(S, E, T, CC, &ICContext); |
11290 | } |
11291 | |
11292 | static void CheckConditionalOperator(Sema &S, ConditionalOperator *E, |
11293 | SourceLocation CC, QualType T) { |
11294 | AnalyzeImplicitConversions(S, E->getCond(), E->getQuestionLoc()); |
11295 | |
11296 | bool Suspicious = false; |
11297 | CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious); |
11298 | CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious); |
11299 | |
11300 | |
11301 | |
11302 | if (!Suspicious) return; |
11303 | |
11304 | |
11305 | if (!S.Diags.isIgnored(diag::warn_impcast_integer_sign_conditional, CC)) |
11306 | return; |
11307 | |
11308 | |
11309 | |
11310 | if (E->getType() == T) return; |
11311 | |
11312 | Suspicious = false; |
11313 | CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(), |
11314 | E->getType(), CC, &Suspicious); |
11315 | if (!Suspicious) |
11316 | CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(), |
11317 | E->getType(), CC, &Suspicious); |
11318 | } |
11319 | |
11320 | |
11321 | |
11322 | static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) { |
11323 | if (S.getLangOpts().Bool) |
11324 | return; |
11325 | if (E->IgnoreParenImpCasts()->getType()->isAtomicType()) |
11326 | return; |
11327 | CheckImplicitConversion(S, E->IgnoreParenImpCasts(), S.Context.BoolTy, CC); |
11328 | } |
11329 | |
11330 | |
11331 | |
11332 | |
11333 | static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, |
11334 | SourceLocation CC) { |
11335 | QualType T = OrigE->getType(); |
11336 | Expr *E = OrigE->IgnoreParenImpCasts(); |
11337 | |
11338 | if (E->isTypeDependent() || E->isValueDependent()) |
11339 | return; |
11340 | |
11341 | |
11342 | |
11343 | if (isa<ConditionalOperator>(E)) { |
11344 | ConditionalOperator *CO = cast<ConditionalOperator>(E); |
11345 | CheckConditionalOperator(S, CO, CC, T); |
11346 | return; |
11347 | } |
11348 | |
11349 | |
11350 | if (CallExpr *Call = dyn_cast<CallExpr>(E)) |
11351 | CheckImplicitArgumentConversions(S, Call, CC); |
11352 | |
11353 | |
11354 | |
11355 | |
11356 | if (E->getType() != T) |
11357 | CheckImplicitConversion(S, E, T, CC); |
11358 | |
11359 | |
11360 | |
11361 | if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) { |
11362 | |
11363 | |
11364 | |
11365 | for (auto *SE : POE->semantics()) |
11366 | if (auto *OVE = dyn_cast<OpaqueValueExpr>(SE)) |
11367 | AnalyzeImplicitConversions(S, OVE->getSourceExpr(), CC); |
11368 | } |
11369 | |
11370 | |
11371 | if (auto *CE = dyn_cast<ExplicitCastExpr>(E)) { |
11372 | E = CE->getSubExpr()->IgnoreParenImpCasts(); |
11373 | if (!CE->getType()->isVoidType() && E->getType()->isAtomicType()) |
11374 | S.Diag(E->getBeginLoc(), diag::warn_atomic_implicit_seq_cst); |
11375 | return AnalyzeImplicitConversions(S, E, CC); |
11376 | } |
11377 | |
11378 | if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { |
11379 | |
11380 | if (BO->isComparisonOp()) |
11381 | return AnalyzeComparison(S, BO); |
11382 | |
11383 | |
11384 | if (BO->getOpcode() == BO_Assign) |
11385 | return AnalyzeAssignment(S, BO); |
11386 | |
11387 | if (BO->isAssignmentOp()) |
11388 | return AnalyzeCompoundAssignment(S, BO); |
11389 | } |
11390 | |
11391 | |
11392 | |
11393 | |
11394 | |
11395 | if (isa<StmtExpr>(E)) return; |
11396 | |
11397 | |
11398 | if (isa<UnaryExprOrTypeTraitExpr>(E)) return; |
11399 | |
11400 | |
11401 | CC = E->getExprLoc(); |
11402 | BinaryOperator *BO = dyn_cast<BinaryOperator>(E); |
11403 | bool IsLogicalAndOperator = BO && BO->getOpcode() == BO_LAnd; |
11404 | for (Stmt *SubStmt : E->children()) { |
11405 | Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt); |
11406 | if (!ChildExpr) |
11407 | continue; |
11408 | |
11409 | if (IsLogicalAndOperator && |
11410 | isa<StringLiteral>(ChildExpr->IgnoreParenImpCasts())) |
11411 | |
11412 | |
11413 | continue; |
11414 | AnalyzeImplicitConversions(S, ChildExpr, CC); |
11415 | } |
11416 | |
11417 | if (BO && BO->isLogicalOp()) { |
11418 | Expr *SubExpr = BO->getLHS()->IgnoreParenImpCasts(); |
11419 | if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr)) |
11420 | ::CheckBoolLikeConversion(S, SubExpr, BO->getExprLoc()); |
11421 | |
11422 | SubExpr = BO->getRHS()->IgnoreParenImpCasts(); |
11423 | if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr)) |
11424 | ::CheckBoolLikeConversion(S, SubExpr, BO->getExprLoc()); |
11425 | } |
11426 | |
11427 | if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) { |
11428 | if (U->getOpcode() == UO_LNot) { |
11429 | ::CheckBoolLikeConversion(S, U->getSubExpr(), CC); |
11430 | } else if (U->getOpcode() != UO_AddrOf) { |
11431 | if (U->getSubExpr()->getType()->isAtomicType()) |
11432 | S.Diag(U->getSubExpr()->getBeginLoc(), |
11433 | diag::warn_atomic_implicit_seq_cst); |
11434 | } |
11435 | } |
11436 | } |
11437 | |
11438 | |
11439 | static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, const QualType &IntT) { |
11440 | |
11441 | |
11442 | if (!E->getType()->isIntegerType()) { |
11443 | S.Diag(E->getBeginLoc(), |
11444 | diag::err_opencl_enqueue_kernel_invalid_local_size_type); |
11445 | return true; |
11446 | } |
11447 | |
11448 | |
11449 | CheckImplicitConversion(S, E, IntT, E->getBeginLoc()); |
11450 | return false; |
11451 | } |
11452 | |
11453 | |
11454 | |
11455 | static bool CheckForReference(Sema &SemaRef, const Expr *E, |
11456 | const PartialDiagnostic &PD) { |
11457 | E = E->IgnoreParenImpCasts(); |
11458 | |
11459 | const FunctionDecl *FD = nullptr; |
11460 | |
11461 | if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { |
11462 | if (!DRE->getDecl()->getType()->isReferenceType()) |
11463 | return false; |
11464 | } else if (const MemberExpr *M = dyn_cast<MemberExpr>(E)) { |
11465 | if (!M->getMemberDecl()->getType()->isReferenceType()) |
11466 | return false; |
11467 | } else if (const CallExpr *Call = dyn_cast<CallExpr>(E)) { |
11468 | if (!Call->getCallReturnType(SemaRef.Context)->isReferenceType()) |
11469 | return false; |
11470 | FD = Call->getDirectCallee(); |
11471 | } else { |
11472 | return false; |
11473 | } |
11474 | |
11475 | SemaRef.Diag(E->getExprLoc(), PD); |
11476 | |
11477 | |
11478 | if (FD) { |
11479 | SemaRef.Diag(FD->getLocation(), diag::note_reference_is_return_value) << FD; |
11480 | } |
11481 | |
11482 | return true; |
11483 | } |
11484 | |
11485 | |
11486 | |
11487 | |
11488 | static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc) { |
11489 | if (Loc.isInvalid()) |
11490 | return false; |
11491 | |
11492 | while (Loc.isMacroID()) { |
11493 | if (SM.isMacroBodyExpansion(Loc)) |
11494 | return true; |
11495 | Loc = SM.getImmediateMacroCallerLoc(Loc); |
11496 | } |
11497 | |
11498 | return false; |
11499 | } |
11500 | |
11501 | |
11502 | |
11503 | |
11504 | |
11505 | |
11506 | |
11507 | void Sema::DiagnoseAlwaysNonNullPointer(Expr *E, |
11508 | Expr::NullPointerConstantKind NullKind, |
11509 | bool IsEqual, SourceRange Range) { |
11510 | if (!E) |
11511 | return; |
11512 | |
11513 | |
11514 | if (E->getExprLoc().isMacroID()) { |
11515 | const SourceManager &SM = getSourceManager(); |
11516 | if (IsInAnyMacroBody(SM, E->getExprLoc()) || |
11517 | IsInAnyMacroBody(SM, Range.getBegin())) |
11518 | return; |
11519 | } |
11520 | E = E->IgnoreImpCasts(); |
11521 | |
11522 | const bool IsCompare = NullKind != Expr::NPCK_NotNull; |
11523 | |
11524 | if (isa<CXXThisExpr>(E)) { |
11525 | unsigned DiagID = IsCompare ? diag::warn_this_null_compare |
11526 | : diag::warn_this_bool_conversion; |
11527 | Diag(E->getExprLoc(), DiagID) << E->getSourceRange() << Range << IsEqual; |
11528 | return; |
11529 | } |
11530 | |
11531 | bool IsAddressOf = false; |
11532 | |
11533 | if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { |
11534 | if (UO->getOpcode() != UO_AddrOf) |
11535 | return; |
11536 | IsAddressOf = true; |
11537 | E = UO->getSubExpr(); |
11538 | } |
11539 | |
11540 | if (IsAddressOf) { |
11541 | unsigned DiagID = IsCompare |
11542 | ? diag::warn_address_of_reference_null_compare |
11543 | : diag::warn_address_of_reference_bool_conversion; |
11544 | PartialDiagnostic PD = PDiag(DiagID) << E->getSourceRange() << Range |
11545 | << IsEqual; |
11546 | if (CheckForReference(*this, E, PD)) { |
11547 | return; |
11548 | } |
11549 | } |
11550 | |
11551 | auto ComplainAboutNonnullParamOrCall = [&](const Attr *NonnullAttr) { |
11552 | bool IsParam = isa<NonNullAttr>(NonnullAttr); |
11553 | std::string Str; |
11554 | llvm::raw_string_ostream S(Str); |
11555 | E->printPretty(S, nullptr, getPrintingPolicy()); |
11556 | unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare |
11557 | : diag::warn_cast_nonnull_to_bool; |
11558 | Diag(E->getExprLoc(), DiagID) << IsParam << S.str() |
11559 | << E->getSourceRange() << Range << IsEqual; |
11560 | Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam; |
11561 | }; |
11562 | |
11563 | |
11564 | if (auto *Call = dyn_cast<CallExpr>(E->IgnoreParenImpCasts())) { |
11565 | if (auto *Callee = Call->getDirectCallee()) { |
11566 | if (const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) { |
11567 | ComplainAboutNonnullParamOrCall(A); |
11568 | return; |
11569 | } |
11570 | } |
11571 | } |
11572 | |
11573 | |
11574 | ValueDecl *D = nullptr; |
11575 | if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) { |
11576 | D = R->getDecl(); |
11577 | } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) { |
11578 | D = M->getMemberDecl(); |
11579 | } |
11580 | |
11581 | |
11582 | if (!D || D->isWeak()) |
11583 | return; |
11584 | |
11585 | |
11586 | if (const auto* PV = dyn_cast<ParmVarDecl>(D)) { |
11587 | if (getCurFunction() && |
11588 | !getCurFunction()->ModifiedNonNullParams.count(PV)) { |
11589 | if (const Attr *A = PV->getAttr<NonNullAttr>()) { |
11590 | ComplainAboutNonnullParamOrCall(A); |
11591 | return; |
11592 | } |
11593 | |
11594 | if (const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) { |
11595 | |
11596 | if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) |
11597 | return; |
11598 | auto ParamIter = llvm::find(FD->parameters(), PV); |
11599 | param_end()", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 11599, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(ParamIter != FD->param_end()); |
11600 | unsigned ParamNo = std::distance(FD->param_begin(), ParamIter); |
11601 | |
11602 | for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) { |
11603 | if (!NonNull->args_size()) { |
11604 | ComplainAboutNonnullParamOrCall(NonNull); |
11605 | return; |
11606 | } |
11607 | |
11608 | for (const ParamIdx &ArgNo : NonNull->args()) { |
11609 | if (ArgNo.getASTIndex() == ParamNo) { |
11610 | ComplainAboutNonnullParamOrCall(NonNull); |
11611 | return; |
11612 | } |
11613 | } |
11614 | } |
11615 | } |
11616 | } |
11617 | } |
11618 | |
11619 | QualType T = D->getType(); |
11620 | const bool IsArray = T->isArrayType(); |
11621 | const bool IsFunction = T->isFunctionType(); |
11622 | |
11623 | |
11624 | if (IsAddressOf && IsFunction) { |
11625 | return; |
11626 | } |
11627 | |
11628 | |
11629 | if (!IsAddressOf && !IsFunction && !IsArray) |
11630 | return; |
11631 | |
11632 | |
11633 | std::string Str; |
11634 | llvm::raw_string_ostream S(Str); |
11635 | E->printPretty(S, nullptr, getPrintingPolicy()); |
11636 | |
11637 | unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare |
11638 | : diag::warn_impcast_pointer_to_bool; |
11639 | enum { |
11640 | AddressOf, |
11641 | FunctionPointer, |
11642 | ArrayPointer |
11643 | } DiagType; |
11644 | if (IsAddressOf) |
11645 | DiagType = AddressOf; |
11646 | else if (IsFunction) |
11647 | DiagType = FunctionPointer; |
11648 | else if (IsArray) |
11649 | DiagType = ArrayPointer; |
11650 | else |
11651 | llvm_unreachable("Could not determine diagnostic."); |
11652 | Diag(E->getExprLoc(), DiagID) << DiagType << S.str() << E->getSourceRange() |
11653 | << Range << IsEqual; |
11654 | |
11655 | if (!IsFunction) |
11656 | return; |
11657 | |
11658 | |
11659 | Diag(E->getExprLoc(), diag::note_function_warning_silence) |
11660 | << FixItHint::CreateInsertion(E->getBeginLoc(), "&"); |
11661 | |
11662 | |
11663 | QualType ReturnType; |
11664 | UnresolvedSet<4> NonTemplateOverloads; |
11665 | tryExprAsCall(*E, ReturnType, NonTemplateOverloads); |
11666 | if (ReturnType.isNull()) |
11667 | return; |
11668 | |
11669 | if (IsCompare) { |
11670 | |
11671 | |
11672 | |
11673 | if (!ReturnType->isPointerType()) { |
11674 | if (NullKind == Expr::NPCK_ZeroExpression || |
11675 | NullKind == Expr::NPCK_ZeroLiteral) { |
11676 | if (!ReturnType->isIntegerType()) |
11677 | return; |
11678 | } else { |
11679 | return; |
11680 | } |
11681 | } |
11682 | } else { |
11683 | |
11684 | |
11685 | if (!ReturnType->isSpecificBuiltinType(BuiltinType::Bool)) |
11686 | return; |
11687 | } |
11688 | Diag(E->getExprLoc(), diag::note_function_to_function_call) |
11689 | << FixItHint::CreateInsertion(getLocForEndOfToken(E->getEndLoc()), "()"); |
11690 | } |
11691 | |
11692 | |
11693 | |
11694 | |
11695 | |
11696 | |
11697 | |
11698 | |
11699 | void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) { |
11700 | |
11701 | if (isUnevaluatedContext()) |
11702 | return; |
11703 | |
11704 | |
11705 | if (E->isTypeDependent() || E->isValueDependent()) |
11706 | return; |
11707 | |
11708 | |
11709 | |
11710 | |
11711 | CheckArrayAccess(E); |
11712 | |
11713 | |
11714 | AnalyzeImplicitConversions(*this, E, CC); |
11715 | } |
11716 | |
11717 | |
11718 | |
11719 | void Sema::CheckBoolLikeConversion(Expr *E, SourceLocation CC) { |
11720 | ::CheckBoolLikeConversion(*this, E, CC); |
11721 | } |
11722 | |
11723 | |
11724 | |
11725 | void Sema::CheckForIntOverflow (Expr *E) { |
11726 | |
11727 | SmallVector<Expr *, 2> Exprs(1, E); |
11728 | |
11729 | do { |
11730 | Expr *OriginalE = Exprs.pop_back_val(); |
11731 | Expr *E = OriginalE->IgnoreParenCasts(); |
11732 | |
11733 | if (isa<BinaryOperator>(E)) { |
11734 | E->EvaluateForOverflow(Context); |
11735 | continue; |
11736 | } |
11737 | |
11738 | if (auto InitList = dyn_cast<InitListExpr>(OriginalE)) |
11739 | Exprs.append(InitList->inits().begin(), InitList->inits().end()); |
11740 | else if (isa<ObjCBoxedExpr>(OriginalE)) |
11741 | E->EvaluateForOverflow(Context); |
11742 | else if (auto Call = dyn_cast<CallExpr>(E)) |
11743 | Exprs.append(Call->arg_begin(), Call->arg_end()); |
11744 | else if (auto Message = dyn_cast<ObjCMessageExpr>(E)) |
11745 | Exprs.append(Message->arg_begin(), Message->arg_end()); |
11746 | } while (!Exprs.empty()); |
11747 | } |
11748 | |
11749 | namespace { |
11750 | |
11751 | |
11752 | |
11753 | class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> { |
11754 | using Base = EvaluatedExprVisitor<SequenceChecker>; |
11755 | |
11756 | |
11757 | |
11758 | |
11759 | |
11760 | |
11761 | class SequenceTree { |
11762 | struct Value { |
11763 | explicit Value(unsigned Parent) : Parent(Parent), Merged(false) {} |
11764 | unsigned Parent : 31; |
11765 | unsigned Merged : 1; |
11766 | }; |
11767 | SmallVector<Value, 8> Values; |
11768 | |
11769 | public: |
11770 | |
11771 | |
11772 | class Seq { |
11773 | friend class SequenceTree; |
11774 | |
11775 | unsigned Index; |
11776 | |
11777 | explicit Seq(unsigned N) : Index(N) {} |
11778 | |
11779 | public: |
11780 | Seq() : Index(0) {} |
11781 | }; |
11782 | |
11783 | SequenceTree() { Values.push_back(Value(0)); } |
11784 | Seq root() const { return Seq(0); } |
11785 | |
11786 | |
11787 | |
11788 | |
11789 | Seq allocate(Seq Parent) { |
11790 | Values.push_back(Value(Parent.Index)); |
11791 | return Seq(Values.size() - 1); |
11792 | } |
11793 | |
11794 | |
11795 | void merge(Seq S) { |
11796 | Values[S.Index].Merged = true; |
11797 | } |
11798 | |
11799 | |
11800 | |
11801 | |
11802 | bool isUnsequenced(Seq Cur, Seq Old) { |
11803 | unsigned C = representative(Cur.Index); |
11804 | unsigned Target = representative(Old.Index); |
11805 | while (C >= Target) { |
11806 | if (C == Target) |
11807 | return true; |
11808 | C = Values[C].Parent; |
11809 | } |
11810 | return false; |
11811 | } |
11812 | |
11813 | private: |
11814 | |
11815 | unsigned representative(unsigned K) { |
11816 | if (Values[K].Merged) |
11817 | |
11818 | return Values[K].Parent = representative(Values[K].Parent); |
11819 | return K; |
11820 | } |
11821 | }; |
11822 | |
11823 | |
11824 | using Object = NamedDecl *; |
11825 | |
11826 | |
11827 | |
11828 | enum UsageKind { |
11829 | |
11830 | UK_Use, |
11831 | |
11832 | |
11833 | |
11834 | UK_ModAsValue, |
11835 | |
11836 | |
11837 | |
11838 | UK_ModAsSideEffect, |
11839 | |
11840 | UK_Count = UK_ModAsSideEffect + 1 |
11841 | }; |
11842 | |
11843 | struct Usage { |
11844 | Expr *Use; |
11845 | SequenceTree::Seq Seq; |
11846 | |
11847 | Usage() : Use(nullptr), Seq() {} |
11848 | }; |
11849 | |
11850 | struct UsageInfo { |
11851 | Usage Uses[UK_Count]; |
11852 | |
11853 | |
11854 | bool Diagnosed; |
11855 | |
11856 | UsageInfo() : Uses(), Diagnosed(false) {} |
11857 | }; |
11858 | using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>; |
11859 | |
11860 | Sema &SemaRef; |
11861 | |
11862 | |
11863 | SequenceTree Tree; |
11864 | |
11865 | |
11866 | UsageInfoMap UsageMap; |
11867 | |
11868 | |
11869 | SequenceTree::Seq Region; |
11870 | |
11871 | |
11872 | |
11873 | SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect = nullptr; |
11874 | |
11875 | |
11876 | |
11877 | SmallVectorImpl<Expr *> &WorkList; |
11878 | |
11879 | |
11880 | |
11881 | |
11882 | |
11883 | |
11884 | struct SequencedSubexpression { |
11885 | SequencedSubexpression(SequenceChecker &Self) |
11886 | : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) { |
11887 | Self.ModAsSideEffect = &ModAsSideEffect; |
11888 | } |
11889 | |
11890 | ~SequencedSubexpression() { |
11891 | for (auto &M : llvm::reverse(ModAsSideEffect)) { |
11892 | UsageInfo &U = Self.UsageMap[M.first]; |
11893 | auto &SideEffectUsage = U.Uses[UK_ModAsSideEffect]; |
11894 | Self.addUsage(U, M.first, SideEffectUsage.Use, UK_ModAsValue); |
11895 | SideEffectUsage = M.second; |
11896 | } |
11897 | Self.ModAsSideEffect = OldModAsSideEffect; |
11898 | } |
11899 | |
11900 | SequenceChecker &Self; |
11901 | SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect; |
11902 | SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect; |
11903 | }; |
11904 | |
11905 | |
11906 | |
11907 | |
11908 | |
11909 | class EvaluationTracker { |
11910 | public: |
11911 | EvaluationTracker(SequenceChecker &Self) |
11912 | : Self(Self), Prev(Self.EvalTracker) { |
11913 | Self.EvalTracker = this; |
11914 | } |
11915 | |
11916 | ~EvaluationTracker() { |
11917 | Self.EvalTracker = Prev; |
11918 | if (Prev) |
11919 | Prev->EvalOK &= EvalOK; |
11920 | } |
11921 | |
11922 | bool evaluate(const Expr *E, bool &Result) { |
11923 | if (!EvalOK || E->isValueDependent()) |
11924 | return false; |
11925 | EvalOK = E->EvaluateAsBooleanCondition(Result, Self.SemaRef.Context); |
11926 | return EvalOK; |
11927 | } |
11928 | |
11929 | private: |
11930 | SequenceChecker &Self; |
11931 | EvaluationTracker *Prev; |
11932 | bool EvalOK = true; |
11933 | } *EvalTracker = nullptr; |
11934 | |
11935 | |
11936 | |
11937 | Object getObject(Expr *E, bool Mod) const { |
11938 | E = E->IgnoreParenCasts(); |
11939 | if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { |
11940 | if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec)) |
11941 | return getObject(UO->getSubExpr(), Mod); |
11942 | } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { |
11943 | if (BO->getOpcode() == BO_Comma) |
11944 | return getObject(BO->getRHS(), Mod); |
11945 | if (Mod && BO->isAssignmentOp()) |
11946 | return getObject(BO->getLHS(), Mod); |
11947 | } else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { |
11948 | |
11949 | if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts())) |
11950 | return ME->getMemberDecl(); |
11951 | } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) |
11952 | |
11953 | return DRE->getDecl(); |
11954 | return nullptr; |
11955 | } |
11956 | |
11957 | |
11958 | void addUsage(UsageInfo &UI, Object O, Expr *Ref, UsageKind UK) { |
11959 | Usage &U = UI.Uses[UK]; |
11960 | if (!U.Use || !Tree.isUnsequenced(Region, U.Seq)) { |
11961 | if (UK == UK_ModAsSideEffect && ModAsSideEffect) |
11962 | ModAsSideEffect->push_back(std::make_pair(O, U)); |
11963 | U.Use = Ref; |
11964 | U.Seq = Region; |
11965 | } |
11966 | } |
11967 | |
11968 | |
11969 | void checkUsage(Object O, UsageInfo &UI, Expr *Ref, UsageKind OtherKind, |
11970 | bool IsModMod) { |
11971 | if (UI.Diagnosed) |
11972 | return; |
11973 | |
11974 | const Usage &U = UI.Uses[OtherKind]; |
11975 | if (!U.Use || !Tree.isUnsequenced(Region, U.Seq)) |
11976 | return; |
11977 | |
11978 | Expr *Mod = U.Use; |
11979 | Expr *ModOrUse = Ref; |
11980 | if (OtherKind == UK_Use) |
11981 | std::swap(Mod, ModOrUse); |
11982 | |
11983 | SemaRef.Diag(Mod->getExprLoc(), |
11984 | IsModMod ? diag::warn_unsequenced_mod_mod |
11985 | : diag::warn_unsequenced_mod_use) |
11986 | << O << SourceRange(ModOrUse->getExprLoc()); |
11987 | UI.Diagnosed = true; |
11988 | } |
11989 | |
11990 | void notePreUse(Object O, Expr *Use) { |
11991 | UsageInfo &U = UsageMap[O]; |
11992 | |
11993 | checkUsage(O, U, Use, UK_ModAsValue, false); |
11994 | } |
11995 | |
11996 | void notePostUse(Object O, Expr *Use) { |
11997 | UsageInfo &U = UsageMap[O]; |
11998 | checkUsage(O, U, Use, UK_ModAsSideEffect, false); |
11999 | addUsage(U, O, Use, UK_Use); |
12000 | } |
12001 | |
12002 | void notePreMod(Object O, Expr *Mod) { |
12003 | UsageInfo &U = UsageMap[O]; |
12004 | |
12005 | checkUsage(O, U, Mod, UK_ModAsValue, true); |
12006 | checkUsage(O, U, Mod, UK_Use, false); |
12007 | } |
12008 | |
12009 | void notePostMod(Object O, Expr *Use, UsageKind UK) { |
12010 | UsageInfo &U = UsageMap[O]; |
12011 | checkUsage(O, U, Use, UK_ModAsSideEffect, true); |
12012 | addUsage(U, O, Use, UK); |
12013 | } |
12014 | |
12015 | public: |
12016 | SequenceChecker(Sema &S, Expr *E, SmallVectorImpl<Expr *> &WorkList) |
12017 | : Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) { |
12018 | Visit(E); |
12019 | } |
12020 | |
12021 | void VisitStmt(Stmt *S) { |
12022 | |
12023 | } |
12024 | |
12025 | void VisitExpr(Expr *E) { |
12026 | |
12027 | Base::VisitStmt(E); |
12028 | } |
12029 | |
12030 | void VisitCastExpr(CastExpr *E) { |
12031 | Object O = Object(); |
12032 | if (E->getCastKind() == CK_LValueToRValue) |
12033 | O = getObject(E->getSubExpr(), false); |
12034 | |
12035 | if (O) |
12036 | notePreUse(O, E); |
12037 | VisitExpr(E); |
12038 | if (O) |
12039 | notePostUse(O, E); |
12040 | } |
12041 | |
12042 | void VisitSequencedExpressions(Expr *SequencedBefore, Expr *SequencedAfter) { |
12043 | SequenceTree::Seq BeforeRegion = Tree.allocate(Region); |
12044 | SequenceTree::Seq AfterRegion = Tree.allocate(Region); |
12045 | SequenceTree::Seq OldRegion = Region; |
12046 | |
12047 | { |
12048 | SequencedSubexpression SeqBefore(*this); |
12049 | Region = BeforeRegion; |
12050 | Visit(SequencedBefore); |
12051 | } |
12052 | |
12053 | Region = AfterRegion; |
12054 | Visit(SequencedAfter); |
12055 | |
12056 | Region = OldRegion; |
12057 | |
12058 | Tree.merge(BeforeRegion); |
12059 | Tree.merge(AfterRegion); |
12060 | } |
12061 | |
12062 | void VisitArraySubscriptExpr(ArraySubscriptExpr *ASE) { |
12063 | |
12064 | |
12065 | |
12066 | if (SemaRef.getLangOpts().CPlusPlus17) |
12067 | VisitSequencedExpressions(ASE->getLHS(), ASE->getRHS()); |
12068 | else |
12069 | Base::VisitStmt(ASE); |
12070 | } |
12071 | |
12072 | void VisitBinComma(BinaryOperator *BO) { |
12073 | |
12074 | |
12075 | |
12076 | |
12077 | VisitSequencedExpressions(BO->getLHS(), BO->getRHS()); |
12078 | } |
12079 | |
12080 | void VisitBinAssign(BinaryOperator *BO) { |
12081 | |
12082 | |
12083 | |
12084 | Object O = getObject(BO->getLHS(), true); |
12085 | if (!O) |
12086 | return VisitExpr(BO); |
12087 | |
12088 | notePreMod(O, BO); |
12089 | |
12090 | |
12091 | |
12092 | |
12093 | |
12094 | |
12095 | |
12096 | if (isa<CompoundAssignOperator>(BO)) |
12097 | notePreUse(O, BO); |
12098 | |
12099 | Visit(BO->getLHS()); |
12100 | |
12101 | if (isa<CompoundAssignOperator>(BO)) |
12102 | notePostUse(O, BO); |
12103 | |
12104 | Visit(BO->getRHS()); |
12105 | |
12106 | |
12107 | |
12108 | |
12109 | |
12110 | notePostMod(O, BO, SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue |
12111 | : UK_ModAsSideEffect); |
12112 | } |
12113 | |
12114 | void VisitCompoundAssignOperator(CompoundAssignOperator *CAO) { |
12115 | VisitBinAssign(CAO); |
12116 | } |
12117 | |
12118 | void VisitUnaryPreInc(UnaryOperator *UO) { VisitUnaryPreIncDec(UO); } |
12119 | void VisitUnaryPreDec(UnaryOperator *UO) { VisitUnaryPreIncDec(UO); } |
12120 | void VisitUnaryPreIncDec(UnaryOperator *UO) { |
12121 | Object O = getObject(UO->getSubExpr(), true); |
12122 | if (!O) |
12123 | return VisitExpr(UO); |
12124 | |
12125 | notePreMod(O, UO); |
12126 | Visit(UO->getSubExpr()); |
12127 | |
12128 | |
12129 | notePostMod(O, UO, SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue |
12130 | : UK_ModAsSideEffect); |
12131 | } |
12132 | |
12133 | void VisitUnaryPostInc(UnaryOperator *UO) { VisitUnaryPostIncDec(UO); } |
12134 | void VisitUnaryPostDec(UnaryOperator *UO) { VisitUnaryPostIncDec(UO); } |
12135 | void VisitUnaryPostIncDec(UnaryOperator *UO) { |
12136 | Object O = getObject(UO->getSubExpr(), true); |
12137 | if (!O) |
12138 | return VisitExpr(UO); |
12139 | |
12140 | notePreMod(O, UO); |
12141 | Visit(UO->getSubExpr()); |
12142 | notePostMod(O, UO, UK_ModAsSideEffect); |
12143 | } |
12144 | |
12145 | |
12146 | void VisitBinLOr(BinaryOperator *BO) { |
12147 | |
12148 | |
12149 | |
12150 | |
12151 | EvaluationTracker Eval(*this); |
12152 | { |
12153 | SequencedSubexpression Sequenced(*this); |
12154 | Visit(BO->getLHS()); |
12155 | } |
12156 | |
12157 | bool Result; |
12158 | if (Eval.evaluate(BO->getLHS(), Result)) { |
12159 | if (!Result) |
12160 | Visit(BO->getRHS()); |
12161 | } else { |
12162 | |
12163 | |
12164 | |
12165 | |
12166 | |
12167 | |
12168 | WorkList.push_back(BO->getRHS()); |
12169 | } |
12170 | } |
12171 | void VisitBinLAnd(BinaryOperator *BO) { |
12172 | EvaluationTracker Eval(*this); |
12173 | { |
12174 | SequencedSubexpression Sequenced(*this); |
12175 | Visit(BO->getLHS()); |
12176 | } |
12177 | |
12178 | bool Result; |
12179 | if (Eval.evaluate(BO->getLHS(), Result)) { |
12180 | if (Result) |
12181 | Visit(BO->getRHS()); |
12182 | } else { |
12183 | WorkList.push_back(BO->getRHS()); |
12184 | } |
12185 | } |
12186 | |
12187 | |
12188 | |
12189 | void VisitAbstractConditionalOperator(AbstractConditionalOperator *CO) { |
12190 | EvaluationTracker Eval(*this); |
12191 | { |
12192 | SequencedSubexpression Sequenced(*this); |
12193 | Visit(CO->getCond()); |
12194 | } |
12195 | |
12196 | bool Result; |
12197 | if (Eval.evaluate(CO->getCond(), Result)) |
12198 | Visit(Result ? CO->getTrueExpr() : CO->getFalseExpr()); |
12199 | else { |
12200 | WorkList.push_back(CO->getTrueExpr()); |
12201 | WorkList.push_back(CO->getFalseExpr()); |
12202 | } |
12203 | } |
12204 | |
12205 | void VisitCallExpr(CallExpr *CE) { |
12206 | |
12207 | |
12208 | |
12209 | |
12210 | |
12211 | |
12212 | SequencedSubexpression Sequenced(*this); |
12213 | Base::VisitCallExpr(CE); |
12214 | |
12215 | |
12216 | } |
12217 | |
12218 | void VisitCXXConstructExpr(CXXConstructExpr *CCE) { |
12219 | |
12220 | SequencedSubexpression Sequenced(*this); |
12221 | |
12222 | if (!CCE->isListInitialization()) |
12223 | return VisitExpr(CCE); |
12224 | |
12225 | |
12226 | SmallVector<SequenceTree::Seq, 32> Elts; |
12227 | SequenceTree::Seq Parent = Region; |
12228 | for (CXXConstructExpr::arg_iterator I = CCE->arg_begin(), |
12229 | E = CCE->arg_end(); |
12230 | I != E; ++I) { |
12231 | Region = Tree.allocate(Parent); |
12232 | Elts.push_back(Region); |
12233 | Visit(*I); |
12234 | } |
12235 | |
12236 | |
12237 | Region = Parent; |
12238 | for (unsigned I = 0; I < Elts.size(); ++I) |
12239 | Tree.merge(Elts[I]); |
12240 | } |
12241 | |
12242 | void VisitInitListExpr(InitListExpr *ILE) { |
12243 | if (!SemaRef.getLangOpts().CPlusPlus11) |
12244 | return VisitExpr(ILE); |
12245 | |
12246 | |
12247 | SmallVector<SequenceTree::Seq, 32> Elts; |
12248 | SequenceTree::Seq Parent = Region; |
12249 | for (unsigned I = 0; I < ILE->getNumInits(); ++I) { |
12250 | Expr *E = ILE->getInit(I); |
12251 | if (!E) continue; |
12252 | Region = Tree.allocate(Parent); |
12253 | Elts.push_back(Region); |
12254 | Visit(E); |
12255 | } |
12256 | |
12257 | |
12258 | Region = Parent; |
12259 | for (unsigned I = 0; I < Elts.size(); ++I) |
12260 | Tree.merge(Elts[I]); |
12261 | } |
12262 | }; |
12263 | |
12264 | } |
12265 | |
12266 | void Sema::CheckUnsequencedOperations(Expr *E) { |
12267 | SmallVector<Expr *, 8> WorkList; |
12268 | WorkList.push_back(E); |
12269 | while (!WorkList.empty()) { |
12270 | Expr *Item = WorkList.pop_back_val(); |
12271 | SequenceChecker(*this, Item, WorkList); |
12272 | } |
12273 | } |
12274 | |
12275 | void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, |
12276 | bool IsConstexpr) { |
12277 | CheckImplicitConversions(E, CheckLoc); |
12278 | if (!E->isInstantiationDependent()) |
12279 | CheckUnsequencedOperations(E); |
12280 | if (!IsConstexpr && !E->isValueDependent()) |
12281 | CheckForIntOverflow(E); |
12282 | DiagnoseMisalignedMembers(); |
12283 | } |
12284 | |
12285 | void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, |
12286 | FieldDecl *BitField, |
12287 | Expr *Init) { |
12288 | (void) AnalyzeBitFieldAssignment(*this, BitField, Init, InitLoc); |
12289 | } |
12290 | |
12291 | static void diagnoseArrayStarInParamType(Sema &S, QualType PType, |
12292 | SourceLocation Loc) { |
12293 | if (!PType->isVariablyModifiedType()) |
12294 | return; |
12295 | if (const auto *PointerTy = dyn_cast<PointerType>(PType)) { |
12296 | diagnoseArrayStarInParamType(S, PointerTy->getPointeeType(), Loc); |
12297 | return; |
12298 | } |
12299 | if (const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) { |
12300 | diagnoseArrayStarInParamType(S, ReferenceTy->getPointeeType(), Loc); |
12301 | return; |
12302 | } |
12303 | if (const auto *ParenTy = dyn_cast<ParenType>(PType)) { |
12304 | diagnoseArrayStarInParamType(S, ParenTy->getInnerType(), Loc); |
12305 | return; |
12306 | } |
12307 | |
12308 | const ArrayType *AT = S.Context.getAsArrayType(PType); |
12309 | if (!AT) |
12310 | return; |
12311 | |
12312 | if (AT->getSizeModifier() != ArrayType::Star) { |
12313 | diagnoseArrayStarInParamType(S, AT->getElementType(), Loc); |
12314 | return; |
12315 | } |
12316 | |
12317 | S.Diag(Loc, diag::err_array_star_in_function_definition); |
12318 | } |
12319 | |
12320 | |
12321 | |
12322 | |
12323 | |
12324 | |
12325 | bool Sema::CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters, |
12326 | bool CheckParameterNames) { |
12327 | bool HasInvalidParm = false; |
12328 | for (ParmVarDecl *Param : Parameters) { |
12329 | |
12330 | |
12331 | |
12332 | |
12333 | |
12334 | if (!Param->isInvalidDecl() && |
12335 | RequireCompleteType(Param->getLocation(), Param->getType(), |
12336 | diag::err_typecheck_decl_incomplete_type)) { |
12337 | Param->setInvalidDecl(); |
12338 | HasInvalidParm = true; |
12339 | } |
12340 | |
12341 | |
12342 | |
12343 | if (CheckParameterNames && |
12344 | Param->getIdentifier() == nullptr && |
12345 | !Param->isImplicit() && |
12346 | !getLangOpts().CPlusPlus) |
12347 | Diag(Param->getLocation(), diag::err_parameter_name_omitted); |
12348 | |
12349 | |
12350 | |
12351 | |
12352 | |
12353 | |
12354 | QualType PType = Param->getOriginalType(); |
12355 | |
12356 | |
12357 | diagnoseArrayStarInParamType(*this, PType, Param->getLocation()); |
12358 | |
12359 | |
12360 | |
12361 | |
12362 | if (!Param->isInvalidDecl()) { |
12363 | if (CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) { |
12364 | if (!ClassDecl->isInvalidDecl() && |
12365 | !ClassDecl->hasIrrelevantDestructor() && |
12366 | !ClassDecl->isDependentContext() && |
12367 | ClassDecl->isParamDestroyedInCallee()) { |
12368 | CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl); |
12369 | MarkFunctionReferenced(Param->getLocation(), Destructor); |
12370 | DiagnoseUseOfDecl(Destructor, Param->getLocation()); |
12371 | } |
12372 | } |
12373 | } |
12374 | |
12375 | |
12376 | |
12377 | |
12378 | |
12379 | if (const auto *Attr = Param->getAttr<PassObjectSizeAttr>()) |
12380 | if (!Param->getType().isConstQualified()) |
12381 | Diag(Param->getLocation(), diag::err_attribute_pointers_only) |
12382 | << Attr->getSpelling() << 1; |
12383 | |
12384 | |
12385 | if (LangOpts.CPlusPlus && !Param->isInvalidDecl()) { |
12386 | |
12387 | |
12388 | DeclContext *DC = Param->getDeclContext(); |
12389 | if (DC && DC->isFunctionOrMethod()) { |
12390 | if (auto *RD = dyn_cast<CXXRecordDecl>(DC->getParent())) |
12391 | CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(), |
12392 | RD, false); |
12393 | } |
12394 | } |
12395 | } |
12396 | |
12397 | return HasInvalidParm; |
12398 | } |
12399 | |
12400 | |
12401 | |
12402 | static CharUnits getDeclAlign(Expr *E, CharUnits TypeAlign, |
12403 | ASTContext &Context) { |
12404 | if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) |
12405 | return Context.getDeclAlign(DRE->getDecl()); |
12406 | |
12407 | if (const auto *ME = dyn_cast<MemberExpr>(E)) |
12408 | return Context.getDeclAlign(ME->getMemberDecl()); |
12409 | |
12410 | return TypeAlign; |
12411 | } |
12412 | |
12413 | |
12414 | |
12415 | void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) { |
12416 | |
12417 | |
12418 | if (getDiagnostics().isIgnored(diag::warn_cast_align, TRange.getBegin())) |
12419 | return; |
12420 | |
12421 | |
12422 | if (T->isDependentType() || Op->getType()->isDependentType()) |
12423 | return; |
12424 | |
12425 | |
12426 | const PointerType *DestPtr = T->getAs<PointerType>(); |
12427 | if (!DestPtr) return; |
12428 | |
12429 | |
12430 | QualType DestPointee = DestPtr->getPointeeType(); |
12431 | if (DestPointee->isIncompleteType()) return; |
12432 | CharUnits DestAlign = Context.getTypeAlignInChars(DestPointee); |
12433 | if (DestAlign.isOne()) return; |
12434 | |
12435 | |
12436 | const PointerType *SrcPtr = Op->getType()->getAs<PointerType>(); |
12437 | if (!SrcPtr) return; |
12438 | QualType SrcPointee = SrcPtr->getPointeeType(); |
12439 | |
12440 | |
12441 | |
12442 | |
12443 | |
12444 | if (SrcPointee->isIncompleteType()) return; |
12445 | |
12446 | CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee); |
12447 | |
12448 | if (auto *CE = dyn_cast<CastExpr>(Op)) { |
12449 | if (CE->getCastKind() == CK_ArrayToPointerDecay) |
12450 | SrcAlign = getDeclAlign(CE->getSubExpr(), SrcAlign, Context); |
12451 | } else if (auto *UO = dyn_cast<UnaryOperator>(Op)) { |
12452 | if (UO->getOpcode() == UO_AddrOf) |
12453 | SrcAlign = getDeclAlign(UO->getSubExpr(), SrcAlign, Context); |
12454 | } |
12455 | |
12456 | if (SrcAlign >= DestAlign) return; |
12457 | |
12458 | Diag(TRange.getBegin(), diag::warn_cast_align) |
12459 | << Op->getType() << T |
12460 | << static_cast<unsigned>(SrcAlign.getQuantity()) |
12461 | << static_cast<unsigned>(DestAlign.getQuantity()) |
12462 | << TRange << Op->getSourceRange(); |
12463 | } |
12464 | |
12465 | |
12466 | |
12467 | |
12468 | |
12469 | |
12470 | static bool IsTailPaddedMemberArray(Sema &S, const llvm::APInt &Size, |
12471 | const NamedDecl *ND) { |
12472 | if (Size != 1 || !ND) return false; |
12473 | |
12474 | const FieldDecl *FD = dyn_cast<FieldDecl>(ND); |
12475 | if (!FD) return false; |
12476 | |
12477 | |
12478 | |
12479 | |
12480 | TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); |
12481 | while (TInfo) { |
12482 | TypeLoc TL = TInfo->getTypeLoc(); |
12483 | |
12484 | if (TypedefTypeLoc TTL = TL.getAs<TypedefTypeLoc>()) { |
12485 | const TypedefNameDecl *TDL = TTL.getTypedefNameDecl(); |
12486 | TInfo = TDL->getTypeSourceInfo(); |
12487 | continue; |
12488 | } |
12489 | if (ConstantArrayTypeLoc CTL = TL.getAs<ConstantArrayTypeLoc>()) { |
12490 | const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL.getSizeExpr()); |
12491 | if (!SizeExpr || SizeExpr->getExprLoc().isMacroID()) |
12492 | return false; |
12493 | } |
12494 | break; |
12495 | } |
12496 | |
12497 | const RecordDecl *RD = dyn_cast<RecordDecl>(FD->getDeclContext()); |
12498 | if (!RD) return false; |
12499 | if (RD->isUnion()) return false; |
12500 | if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { |
12501 | if (!CRD->isStandardLayout()) return false; |
12502 | } |
12503 | |
12504 | |
12505 | const Decl *D = FD; |
12506 | while ((D = D->getNextDeclInContext())) |
12507 | if (isa<FieldDecl>(D)) |
12508 | return false; |
12509 | return true; |
12510 | } |
12511 | |
12512 | void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, |
12513 | const ArraySubscriptExpr *ASE, |
12514 | bool AllowOnePastEnd, bool IndexNegated) { |
12515 | IndexExpr = IndexExpr->IgnoreParenImpCasts(); |
12516 | if (IndexExpr->isValueDependent()) |
12517 | return; |
12518 | |
12519 | const Type *EffectiveType = |
12520 | BaseExpr->getType()->getPointeeOrArrayElementType(); |
12521 | BaseExpr = BaseExpr->IgnoreParenCasts(); |
12522 | const ConstantArrayType *ArrayTy = |
12523 | Context.getAsConstantArrayType(BaseExpr->getType()); |
12524 | |
12525 | if (!ArrayTy) |
12526 | return; |
12527 | |
12528 | const Type *BaseType = ArrayTy->getElementType().getTypePtr(); |
12529 | if (EffectiveType->isDependentType() || BaseType->isDependentType()) |
12530 | return; |
12531 | |
12532 | Expr::EvalResult Result; |
12533 | if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects)) |
12534 | return; |
12535 | |
12536 | llvm::APSInt index = Result.Val.getInt(); |
12537 | if (IndexNegated) |
12538 | index = -index; |
12539 | |
12540 | const NamedDecl *ND = nullptr; |
12541 | if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr)) |
12542 | ND = DRE->getDecl(); |
12543 | if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr)) |
12544 | ND = ME->getMemberDecl(); |
12545 | |
12546 | if (index.isUnsigned() || !index.isNegative()) { |
12547 | |
12548 | |
12549 | |
12550 | |
12551 | |
12552 | |
12553 | if (BaseType->isIncompleteType()) |
12554 | return; |
12555 | |
12556 | llvm::APInt size = ArrayTy->getSize(); |
12557 | if (!size.isStrictlyPositive()) |
12558 | return; |
12559 | |
12560 | if (BaseType != EffectiveType) { |
12561 | |
12562 | uint64_t ptrarith_typesize = Context.getTypeSize(EffectiveType); |
12563 | uint64_t array_typesize = Context.getTypeSize(BaseType); |
12564 | |
12565 | if (!ptrarith_typesize) ptrarith_typesize = 1; |
12566 | if (ptrarith_typesize != array_typesize) { |
12567 | |
12568 | uint64_t ratio = array_typesize / ptrarith_typesize; |
12569 | |
12570 | |
12571 | if (ptrarith_typesize * ratio == array_typesize) |
12572 | size *= llvm::APInt(size.getBitWidth(), ratio); |
12573 | } |
12574 | } |
12575 | |
12576 | if (size.getBitWidth() > index.getBitWidth()) |
12577 | index = index.zext(size.getBitWidth()); |
12578 | else if (size.getBitWidth() < index.getBitWidth()) |
12579 | size = size.zext(index.getBitWidth()); |
12580 | |
12581 | |
12582 | |
12583 | |
12584 | |
12585 | if (AllowOnePastEnd ? index.ule(size) : index.ult(size)) |
12586 | return; |
12587 | |
12588 | |
12589 | |
12590 | |
12591 | if (IsTailPaddedMemberArray(*this, size, ND)) |
12592 | return; |
12593 | |
12594 | |
12595 | |
12596 | |
12597 | if (ASE) { |
12598 | SourceLocation RBracketLoc = SourceMgr.getSpellingLoc( |
12599 | ASE->getRBracketLoc()); |
12600 | if (SourceMgr.isInSystemHeader(RBracketLoc)) { |
12601 | SourceLocation IndexLoc = |
12602 | SourceMgr.getSpellingLoc(IndexExpr->getBeginLoc()); |
12603 | if (SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc)) |
12604 | return; |
12605 | } |
12606 | } |
12607 | |
12608 | unsigned DiagID = diag::warn_ptr_arith_exceeds_bounds; |
12609 | if (ASE) |
12610 | DiagID = diag::warn_array_index_exceeds_bounds; |
12611 | |
12612 | DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr, |
12613 | PDiag(DiagID) << index.toString(10, true) |
12614 | << size.toString(10, true) |
12615 | << (unsigned)size.getLimitedValue(~0U) |
12616 | << IndexExpr->getSourceRange()); |
12617 | } else { |
12618 | unsigned DiagID = diag::warn_array_index_precedes_bounds; |
12619 | if (!ASE) { |
12620 | DiagID = diag::warn_ptr_arith_precedes_bounds; |
12621 | if (index.isNegative()) index = -index; |
12622 | } |
12623 | |
12624 | DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr, |
12625 | PDiag(DiagID) << index.toString(10, true) |
12626 | << IndexExpr->getSourceRange()); |
12627 | } |
12628 | |
12629 | if (!ND) { |
12630 | |
12631 | while (const ArraySubscriptExpr *ASE = |
12632 | dyn_cast<ArraySubscriptExpr>(BaseExpr)) |
12633 | BaseExpr = ASE->getBase()->IgnoreParenCasts(); |
12634 | if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr)) |
12635 | ND = DRE->getDecl(); |
12636 | if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr)) |
12637 | ND = ME->getMemberDecl(); |
12638 | } |
12639 | |
12640 | if (ND) |
12641 | DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr, |
12642 | PDiag(diag::note_array_index_out_of_bounds) |
12643 | << ND->getDeclName()); |
12644 | } |
12645 | |
12646 | void Sema::CheckArrayAccess(const Expr *expr) { |
12647 | int AllowOnePastEnd = 0; |
12648 | while (expr) { |
12649 | expr = expr->IgnoreParenImpCasts(); |
12650 | switch (expr->getStmtClass()) { |
12651 | case Stmt::ArraySubscriptExprClass: { |
12652 | const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr); |
12653 | CheckArrayAccess(ASE->getBase(), ASE->getIdx(), ASE, |
12654 | AllowOnePastEnd > 0); |
12655 | expr = ASE->getBase(); |
12656 | break; |
12657 | } |
12658 | case Stmt::MemberExprClass: { |
12659 | expr = cast<MemberExpr>(expr)->getBase(); |
12660 | break; |
12661 | } |
12662 | case Stmt::OMPArraySectionExprClass: { |
12663 | const OMPArraySectionExpr *ASE = cast<OMPArraySectionExpr>(expr); |
12664 | if (ASE->getLowerBound()) |
12665 | CheckArrayAccess(ASE->getBase(), ASE->getLowerBound(), |
12666 | , AllowOnePastEnd > 0); |
12667 | return; |
12668 | } |
12669 | case Stmt::UnaryOperatorClass: { |
12670 | |
12671 | const UnaryOperator *UO = cast<UnaryOperator>(expr); |
12672 | expr = UO->getSubExpr(); |
12673 | switch (UO->getOpcode()) { |
12674 | case UO_AddrOf: |
12675 | AllowOnePastEnd++; |
12676 | break; |
12677 | case UO_Deref: |
12678 | AllowOnePastEnd--; |
12679 | break; |
12680 | default: |
12681 | return; |
12682 | } |
12683 | break; |
12684 | } |
12685 | case Stmt::ConditionalOperatorClass: { |
12686 | const ConditionalOperator *cond = cast<ConditionalOperator>(expr); |
12687 | if (const Expr *lhs = cond->getLHS()) |
12688 | CheckArrayAccess(lhs); |
12689 | if (const Expr *rhs = cond->getRHS()) |
12690 | CheckArrayAccess(rhs); |
12691 | return; |
12692 | } |
12693 | case Stmt::CXXOperatorCallExprClass: { |
12694 | const auto *OCE = cast<CXXOperatorCallExpr>(expr); |
12695 | for (const auto *Arg : OCE->arguments()) |
12696 | CheckArrayAccess(Arg); |
12697 | return; |
12698 | } |
12699 | default: |
12700 | return; |
12701 | } |
12702 | } |
12703 | } |
12704 | |
12705 | |
12706 | |
12707 | namespace { |
12708 | |
12709 | struct RetainCycleOwner { |
12710 | VarDecl *Variable = nullptr; |
12711 | SourceRange Range; |
12712 | SourceLocation Loc; |
12713 | bool Indirect = false; |
12714 | |
12715 | RetainCycleOwner() = default; |
12716 | |
12717 | void setLocsFrom(Expr *e) { |
12718 | Loc = e->getExprLoc(); |
12719 | Range = e->getSourceRange(); |
12720 | } |
12721 | }; |
12722 | |
12723 | } |
12724 | |
12725 | |
12726 | |
12727 | static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner) { |
12728 | |
12729 | |
12730 | |
12731 | if (var->getType().getObjCLifetime() != Qualifiers::OCL_Strong) |
12732 | return false; |
12733 | |
12734 | owner.Variable = var; |
12735 | if (ref) |
12736 | owner.setLocsFrom(ref); |
12737 | return true; |
12738 | } |
12739 | |
12740 | static bool findRetainCycleOwner(Sema &S, Expr *e, RetainCycleOwner &owner) { |
12741 | while (true) { |
12742 | e = e->IgnoreParens(); |
12743 | if (CastExpr *cast = dyn_cast<CastExpr>(e)) { |
12744 | switch (cast->getCastKind()) { |
12745 | case CK_BitCast: |
12746 | case CK_LValueBitCast: |
12747 | case CK_LValueToRValue: |
12748 | case CK_ARCReclaimReturnedObject: |
12749 | e = cast->getSubExpr(); |
12750 | continue; |
12751 | |
12752 | default: |
12753 | return false; |
12754 | } |
12755 | } |
12756 | |
12757 | if (ObjCIvarRefExpr *ref = dyn_cast<ObjCIvarRefExpr>(e)) { |
12758 | ObjCIvarDecl *ivar = ref->getDecl(); |
12759 | if (ivar->getType().getObjCLifetime() != Qualifiers::OCL_Strong) |
12760 | return false; |
12761 | |
12762 | |
12763 | if (!findRetainCycleOwner(S, ref->getBase(), owner)) |
12764 | return false; |
12765 | |
12766 | if (ref->isFreeIvar()) owner.setLocsFrom(ref); |
12767 | owner.Indirect = true; |
12768 | return true; |
12769 | } |
12770 | |
12771 | if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e)) { |
12772 | VarDecl *var = dyn_cast<VarDecl>(ref->getDecl()); |
12773 | if (!var) return false; |
12774 | return considerVariable(var, ref, owner); |
12775 | } |
12776 | |
12777 | if (MemberExpr *member = dyn_cast<MemberExpr>(e)) { |
12778 | if (member->isArrow()) return false; |
12779 | |
12780 | |
12781 | e = member->getBase(); |
12782 | continue; |
12783 | } |
12784 | |
12785 | if (PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) { |
12786 | |
12787 | ObjCPropertyRefExpr *pre |
12788 | = dyn_cast<ObjCPropertyRefExpr>(pseudo->getSyntacticForm() |
12789 | ->IgnoreParens()); |
12790 | if (!pre) return false; |
12791 | if (pre->isImplicitProperty()) return false; |
12792 | ObjCPropertyDecl *property = pre->getExplicitProperty(); |
12793 | if (!property->isRetaining() && |
12794 | !(property->getPropertyIvarDecl() && |
12795 | property->getPropertyIvarDecl()->getType() |
12796 | .getObjCLifetime() == Qualifiers::OCL_Strong)) |
12797 | return false; |
12798 | |
12799 | owner.Indirect = true; |
12800 | if (pre->isSuperReceiver()) { |
12801 | owner.Variable = S.getCurMethodDecl()->getSelfDecl(); |
12802 | if (!owner.Variable) |
12803 | return false; |
12804 | owner.Loc = pre->getLocation(); |
12805 | owner.Range = pre->getSourceRange(); |
12806 | return true; |
12807 | } |
12808 | e = const_cast<Expr*>(cast<OpaqueValueExpr>(pre->getBase()) |
12809 | ->getSourceExpr()); |
12810 | continue; |
12811 | } |
12812 | |
12813 | |
12814 | |
12815 | return false; |
12816 | } |
12817 | } |
12818 | |
12819 | namespace { |
12820 | |
12821 | struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> { |
12822 | ASTContext &Context; |
12823 | VarDecl *Variable; |
12824 | Expr *Capturer = nullptr; |
12825 | bool VarWillBeReased = false; |
12826 | |
12827 | FindCaptureVisitor(ASTContext &Context, VarDecl *variable) |
12828 | : EvaluatedExprVisitor<FindCaptureVisitor>(Context), |
12829 | Context(Context), Variable(variable) {} |
12830 | |
12831 | void VisitDeclRefExpr(DeclRefExpr *ref) { |
12832 | if (ref->getDecl() == Variable && !Capturer) |
12833 | Capturer = ref; |
12834 | } |
12835 | |
12836 | void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) { |
12837 | if (Capturer) return; |
12838 | Visit(ref->getBase()); |
12839 | if (Capturer && ref->isFreeIvar()) |
12840 | Capturer = ref; |
12841 | } |
12842 | |
12843 | void VisitBlockExpr(BlockExpr *block) { |
12844 | |
12845 | if (block->getBlockDecl()->capturesVariable(Variable)) |
12846 | Visit(block->getBlockDecl()->getBody()); |
12847 | } |
12848 | |
12849 | void VisitOpaqueValueExpr(OpaqueValueExpr *OVE) { |
12850 | if (Capturer) return; |
12851 | if (OVE->getSourceExpr()) |
12852 | Visit(OVE->getSourceExpr()); |
12853 | } |
12854 | |
12855 | void VisitBinaryOperator(BinaryOperator *BinOp) { |
12856 | if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign) |
12857 | return; |
12858 | Expr *LHS = BinOp->getLHS(); |
12859 | if (const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(LHS)) { |
12860 | if (DRE->getDecl() != Variable) |
12861 | return; |
12862 | if (Expr *RHS = BinOp->getRHS()) { |
12863 | RHS = RHS->IgnoreParenCasts(); |
12864 | llvm::APSInt Value; |
12865 | VarWillBeReased = |
12866 | (RHS && RHS->isIntegerConstantExpr(Value, Context) && Value == 0); |
12867 | } |
12868 | } |
12869 | } |
12870 | }; |
12871 | |
12872 | } |
12873 | |
12874 | |
12875 | |
12876 | static Expr *findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner) { |
12877 | assert(owner.Variable && owner.Loc.isValid()); |
12878 | |
12879 | e = e->IgnoreParenCasts(); |
12880 | |
12881 | |
12882 | if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(e)) { |
12883 | Selector Cmd = ME->getSelector(); |
12884 | if (Cmd.isUnarySelector() && Cmd.getNameForSlot(0) == "copy") { |
12885 | e = ME->getInstanceReceiver(); |
12886 | if (!e) |
12887 | return nullptr; |
12888 | e = e->IgnoreParenCasts(); |
12889 | } |
12890 | } else if (CallExpr *CE = dyn_cast<CallExpr>(e)) { |
12891 | if (CE->getNumArgs() == 1) { |
12892 | FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl()); |
12893 | if (Fn) { |
12894 | const IdentifierInfo *FnI = Fn->getIdentifier(); |
12895 | if (FnI && FnI->isStr("_Block_copy")) { |
12896 | e = CE->getArg(0)->IgnoreParenCasts(); |
12897 | } |
12898 | } |
12899 | } |
12900 | } |
12901 | |
12902 | BlockExpr *block = dyn_cast<BlockExpr>(e); |
12903 | if (!block || !block->getBlockDecl()->capturesVariable(owner.Variable)) |
12904 | return nullptr; |
12905 | |
12906 | FindCaptureVisitor visitor(S.Context, owner.Variable); |
12907 | visitor.Visit(block->getBlockDecl()->getBody()); |
12908 | return visitor.VarWillBeReased ? nullptr : visitor.Capturer; |
12909 | } |
12910 | |
12911 | static void diagnoseRetainCycle(Sema &S, Expr *capturer, |
12912 | RetainCycleOwner &owner) { |
12913 | assert(capturer); |
12914 | assert(owner.Variable && owner.Loc.isValid()); |
12915 | |
12916 | S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle) |
12917 | << owner.Variable << capturer->getSourceRange(); |
12918 | S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner) |
12919 | << owner.Indirect << owner.Range; |
12920 | } |
12921 | |
12922 | |
12923 | |
12924 | static bool isSetterLikeSelector(Selector sel) { |
12925 | if (sel.isUnarySelector()) return false; |
12926 | |
12927 | StringRef str = sel.getNameForSlot(0); |
12928 | while (!str.empty() && str.front() == '_') str = str.substr(1); |
12929 | if (str.startswith("set")) |
12930 | str = str.substr(3); |
12931 | else if (str.startswith("add")) { |
12932 | |
12933 | if (sel.getNumArgs() == 1 && str.startswith("addOperationWithBlock")) |
12934 | return false; |
12935 | str = str.substr(3); |
12936 | } |
12937 | else |
12938 | return false; |
12939 | |
12940 | if (str.empty()) return true; |
12941 | return !isLowercase(str.front()); |
12942 | } |
12943 | |
12944 | static Optional<int> GetNSMutableArrayArgumentIndex(Sema &S, |
12945 | ObjCMessageExpr *Message) { |
12946 | bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass( |
12947 | Message->getReceiverInterface(), |
12948 | NSAPI::ClassId_NSMutableArray); |
12949 | if (!IsMutableArray) { |
12950 | return None; |
12951 | } |
12952 | |
12953 | Selector Sel = Message->getSelector(); |
12954 | |
12955 | Optional<NSAPI::NSArrayMethodKind> MKOpt = |
12956 | S.NSAPIObj->getNSArrayMethodKind(Sel); |
12957 | if (!MKOpt) { |
12958 | return None; |
12959 | } |
12960 | |
12961 | NSAPI::NSArrayMethodKind MK = *MKOpt; |
12962 | |
12963 | switch (MK) { |
12964 | case NSAPI::NSMutableArr_addObject: |
12965 | case NSAPI::NSMutableArr_insertObjectAtIndex: |
12966 | case NSAPI::NSMutableArr_setObjectAtIndexedSubscript: |
12967 | return 0; |
12968 | case NSAPI::NSMutableArr_replaceObjectAtIndex: |
12969 | return 1; |
12970 | |
12971 | default: |
12972 | return None; |
12973 | } |
12974 | |
12975 | return None; |
12976 | } |
12977 | |
12978 | static |
12979 | Optional<int> GetNSMutableDictionaryArgumentIndex(Sema &S, |
12980 | ObjCMessageExpr *Message) { |
12981 | bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass( |
12982 | Message->getReceiverInterface(), |
12983 | NSAPI::ClassId_NSMutableDictionary); |
12984 | if (!IsMutableDictionary) { |
12985 | return None; |
12986 | } |
12987 | |
12988 | Selector Sel = Message->getSelector(); |
12989 | |
12990 | Optional<NSAPI::NSDictionaryMethodKind> MKOpt = |
12991 | S.NSAPIObj->getNSDictionaryMethodKind(Sel); |
12992 | if (!MKOpt) { |
12993 | return None; |
12994 | } |
12995 | |
12996 | NSAPI::NSDictionaryMethodKind MK = *MKOpt; |
12997 | |
12998 | switch (MK) { |
12999 | case NSAPI::NSMutableDict_setObjectForKey: |
13000 | case NSAPI::NSMutableDict_setValueForKey: |
13001 | case NSAPI::NSMutableDict_setObjectForKeyedSubscript: |
13002 | return 0; |
13003 | |
13004 | default: |
13005 | return None; |
13006 | } |
13007 | |
13008 | return None; |
13009 | } |
13010 | |
13011 | static Optional<int> GetNSSetArgumentIndex(Sema &S, ObjCMessageExpr *Message) { |
13012 | bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass( |
13013 | Message->getReceiverInterface(), |
13014 | NSAPI::ClassId_NSMutableSet); |
13015 | |
13016 | bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass( |
13017 | Message->getReceiverInterface(), |
13018 | NSAPI::ClassId_NSMutableOrderedSet); |
13019 | if (!IsMutableSet && !IsMutableOrderedSet) { |
13020 | return None; |
13021 | } |
13022 | |
13023 | Selector Sel = Message->getSelector(); |
13024 | |
13025 | Optional<NSAPI::NSSetMethodKind> MKOpt = S.NSAPIObj->getNSSetMethodKind(Sel); |
13026 | if (!MKOpt) { |
13027 | return None; |
13028 | } |
13029 | |
13030 | NSAPI::NSSetMethodKind MK = *MKOpt; |
13031 | |
13032 | switch (MK) { |
13033 | case NSAPI::NSMutableSet_addObject: |
13034 | case NSAPI::NSOrderedSet_setObjectAtIndex: |
13035 | case NSAPI::NSOrderedSet_setObjectAtIndexedSubscript: |
13036 | case NSAPI::NSOrderedSet_insertObjectAtIndex: |
13037 | return 0; |
13038 | case NSAPI::NSOrderedSet_replaceObjectAtIndexWithObject: |
13039 | return 1; |
13040 | } |
13041 | |
13042 | return None; |
13043 | } |
13044 | |
13045 | void Sema::CheckObjCCircularContainer(ObjCMessageExpr *Message) { |
13046 | if (!Message->isInstanceMessage()) { |
13047 | return; |
13048 | } |
13049 | |
13050 | Optional<int> ArgOpt; |
13051 | |
13052 | if (!(ArgOpt = GetNSMutableArrayArgumentIndex(*this, Message)) && |
13053 | !(ArgOpt = GetNSMutableDictionaryArgumentIndex(*this, Message)) && |
13054 | !(ArgOpt = GetNSSetArgumentIndex(*this, Message))) { |
13055 | return; |
13056 | } |
13057 | |
13058 | int ArgIndex = *ArgOpt; |
13059 | |
13060 | Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts(); |
13061 | if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Arg)) { |
13062 | Arg = OE->getSourceExpr()->IgnoreImpCasts(); |
13063 | } |
13064 | |
13065 | if (Message->getReceiverKind() == ObjCMessageExpr::SuperInstance) { |
13066 | if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { |
13067 | if (ArgRE->isObjCSelfExpr()) { |
13068 | Diag(Message->getSourceRange().getBegin(), |
13069 | diag::warn_objc_circular_container) |
13070 | << ArgRE->getDecl() << StringRef("'super'"); |
13071 | } |
13072 | } |
13073 | } else { |
13074 | Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); |
13075 | |
13076 | if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Receiver)) { |
13077 | Receiver = OE->getSourceExpr()->IgnoreImpCasts(); |
13078 | } |
13079 | |
13080 | if (DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) { |
13081 | if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { |
13082 | if (ReceiverRE->getDecl() == ArgRE->getDecl()) { |
13083 | ValueDecl *Decl = ReceiverRE->getDecl(); |
13084 | Diag(Message->getSourceRange().getBegin(), |
13085 | diag::warn_objc_circular_container) |
13086 | << Decl << Decl; |
13087 | if (!ArgRE->isObjCSelfExpr()) { |
13088 | Diag(Decl->getLocation(), |
13089 | diag::note_objc_circular_container_declared_here) |
13090 | << Decl; |
13091 | } |
13092 | } |
13093 | } |
13094 | } else if (ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) { |
13095 | if (ObjCIvarRefExpr *IvarArgRE = dyn_cast<ObjCIvarRefExpr>(Arg)) { |
13096 | if (IvarRE->getDecl() == IvarArgRE->getDecl()) { |
13097 | ObjCIvarDecl *Decl = IvarRE->getDecl(); |
13098 | Diag(Message->getSourceRange().getBegin(), |
13099 | diag::warn_objc_circular_container) |
13100 | << Decl << Decl; |
13101 | Diag(Decl->getLocation(), |
13102 | diag::note_objc_circular_container_declared_here) |
13103 | << Decl; |
13104 | } |
13105 | } |
13106 | } |
13107 | } |
13108 | } |
13109 | |
13110 | |
13111 | void Sema::checkRetainCycles(ObjCMessageExpr *msg) { |
13112 | |
13113 | if (!msg->isInstanceMessage() || !isSetterLikeSelector(msg->getSelector())) |
13114 | return; |
13115 | |
13116 | |
13117 | RetainCycleOwner owner; |
13118 | if (msg->getReceiverKind() == ObjCMessageExpr::Instance) { |
13119 | if (!findRetainCycleOwner(*this, msg->getInstanceReceiver(), owner)) |
13120 | return; |
13121 | } else { |
13122 | getReceiverKind() == ObjCMessageExpr..SuperInstance", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 13122, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(msg->getReceiverKind() == ObjCMessageExpr::SuperInstance); |
13123 | owner.Variable = getCurMethodDecl()->getSelfDecl(); |
13124 | owner.Loc = msg->getSuperLoc(); |
13125 | owner.Range = msg->getSuperLoc(); |
13126 | } |
13127 | |
13128 | |
13129 | const ObjCMethodDecl *MD = msg->getMethodDecl(); |
13130 | for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) { |
13131 | if (Expr *capturer = findCapturingExpr(*this, msg->getArg(i), owner)) { |
13132 | |
13133 | if (MD && MD->parameters()[i]->hasAttr<NoEscapeAttr>()) |
13134 | continue; |
13135 | return diagnoseRetainCycle(*this, capturer, owner); |
13136 | } |
13137 | } |
13138 | } |
13139 | |
13140 | |
13141 | void Sema::checkRetainCycles(Expr *receiver, Expr *argument) { |
13142 | RetainCycleOwner owner; |
13143 | if (!findRetainCycleOwner(*this, receiver, owner)) |
13144 | return; |
13145 | |
13146 | if (Expr *capturer = findCapturingExpr(*this, argument, owner)) |
13147 | diagnoseRetainCycle(*this, capturer, owner); |
13148 | } |
13149 | |
13150 | void Sema::checkRetainCycles(VarDecl *Var, Expr *Init) { |
13151 | RetainCycleOwner Owner; |
13152 | if (!considerVariable(Var, , Owner)) |
13153 | return; |
13154 | |
13155 | |
13156 | |
13157 | Owner.Loc = Var->getLocation(); |
13158 | Owner.Range = Var->getSourceRange(); |
13159 | |
13160 | if (Expr *Capturer = findCapturingExpr(*this, Init, Owner)) |
13161 | diagnoseRetainCycle(*this, Capturer, Owner); |
13162 | } |
13163 | |
13164 | static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, |
13165 | Expr *RHS, bool isProperty) { |
13166 | |
13167 | |
13168 | |
13169 | RHS = RHS->IgnoreParenImpCasts(); |
13170 | |
13171 | |
13172 | |
13173 | Sema::ObjCLiteralKind Kind = S.CheckLiteralKind(RHS); |
13174 | if (Kind == Sema::LK_String || Kind == Sema::LK_None) |
13175 | return false; |
13176 | |
13177 | S.Diag(Loc, diag::warn_arc_literal_assign) |
13178 | << (unsigned) Kind |
13179 | << (isProperty ? 0 : 1) |
13180 | << RHS->getSourceRange(); |
13181 | |
13182 | return true; |
13183 | } |
13184 | |
13185 | static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, |
13186 | Qualifiers::ObjCLifetime LT, |
13187 | Expr *RHS, bool isProperty) { |
13188 | |
13189 | while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) { |
13190 | if (cast->getCastKind() == CK_ARCConsumeObject) { |
13191 | S.Diag(Loc, diag::warn_arc_retained_assign) |
13192 | << (LT == Qualifiers::OCL_ExplicitNone) |
13193 | << (isProperty ? 0 : 1) |
13194 | << RHS->getSourceRange(); |
13195 | return true; |
13196 | } |
13197 | RHS = cast->getSubExpr(); |
13198 | } |
13199 | |
13200 | if (LT == Qualifiers::OCL_Weak && |
13201 | checkUnsafeAssignLiteral(S, Loc, RHS, isProperty)) |
13202 | return true; |
13203 | |
13204 | return false; |
13205 | } |
13206 | |
13207 | bool Sema::checkUnsafeAssigns(SourceLocation Loc, |
13208 | QualType LHS, Expr *RHS) { |
13209 | Qualifiers::ObjCLifetime LT = LHS.getObjCLifetime(); |
13210 | |
13211 | if (LT != Qualifiers::OCL_Weak && LT != Qualifiers::OCL_ExplicitNone) |
13212 | return false; |
13213 | |
13214 | if (checkUnsafeAssignObject(*this, Loc, LT, RHS, false)) |
13215 | return true; |
13216 | |
13217 | return false; |
13218 | } |
13219 | |
13220 | void Sema::checkUnsafeExprAssigns(SourceLocation Loc, |
13221 | Expr *LHS, Expr *RHS) { |
13222 | QualType LHSType; |
13223 | |
13224 | |
13225 | ObjCPropertyRefExpr *PRE |
13226 | = dyn_cast<ObjCPropertyRefExpr>(LHS->IgnoreParens()); |
13227 | if (PRE && !PRE->isImplicitProperty()) { |
13228 | const ObjCPropertyDecl *PD = PRE->getExplicitProperty(); |
13229 | if (PD) |
13230 | LHSType = PD->getType(); |
13231 | } |
13232 | |
13233 | if (LHSType.isNull()) |
13234 | LHSType = LHS->getType(); |
13235 | |
13236 | Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime(); |
13237 | |
13238 | if (LT == Qualifiers::OCL_Weak) { |
13239 | if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc)) |
13240 | getCurFunction()->markSafeWeakUse(LHS); |
13241 | } |
13242 | |
13243 | if (checkUnsafeAssigns(Loc, LHSType, RHS)) |
13244 | return; |
13245 | |
13246 | |
13247 | if (LT != Qualifiers::OCL_None) |
13248 | return; |
13249 | |
13250 | if (PRE) { |
13251 | if (PRE->isImplicitProperty()) |
13252 | return; |
13253 | const ObjCPropertyDecl *PD = PRE->getExplicitProperty(); |
13254 | if (!PD) |
13255 | return; |
13256 | |
13257 | unsigned Attributes = PD->getPropertyAttributes(); |
13258 | if (Attributes & ObjCPropertyDecl::OBJC_PR_assign) { |
13259 | |
13260 | |
13261 | |
13262 | unsigned AsWrittenAttr = PD->getPropertyAttributesAsWritten(); |
13263 | if (!(AsWrittenAttr & ObjCPropertyDecl::OBJC_PR_assign) && |
13264 | LHSType->isObjCRetainableType()) |
13265 | return; |
13266 | |
13267 | while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) { |
13268 | if (cast->getCastKind() == CK_ARCConsumeObject) { |
13269 | Diag(Loc, diag::warn_arc_retained_property_assign) |
13270 | << RHS->getSourceRange(); |
13271 | return; |
13272 | } |
13273 | RHS = cast->getSubExpr(); |
13274 | } |
13275 | } |
13276 | else if (Attributes & ObjCPropertyDecl::OBJC_PR_weak) { |
13277 | if (checkUnsafeAssignObject(*this, Loc, Qualifiers::OCL_Weak, RHS, true)) |
13278 | return; |
13279 | } |
13280 | } |
13281 | } |
13282 | |
13283 | |
13284 | |
13285 | static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, |
13286 | SourceLocation StmtLoc, |
13287 | const NullStmt *Body) { |
13288 | |
13289 | |
13290 | |
13291 | |
13292 | |
13293 | if (Body->hasLeadingEmptyMacro()) |
13294 | return false; |
13295 | |
13296 | |
13297 | bool StmtLineInvalid; |
13298 | unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc, |
13299 | &StmtLineInvalid); |
13300 | if (StmtLineInvalid) |
13301 | return false; |
13302 | |
13303 | bool BodyLineInvalid; |
13304 | unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->getSemiLoc(), |
13305 | &BodyLineInvalid); |
13306 | if (BodyLineInvalid) |
13307 | return false; |
13308 | |
13309 | |
13310 | if (StmtLine != BodyLine) |
13311 | return false; |
13312 | |
13313 | return true; |
13314 | } |
13315 | |
13316 | void Sema::DiagnoseEmptyStmtBody(SourceLocation StmtLoc, |
13317 | const Stmt *Body, |
13318 | unsigned DiagID) { |
13319 | |
13320 | |
13321 | if (CurrentInstantiationScope) |
13322 | return; |
13323 | |
13324 | |
13325 | const NullStmt *NBody = dyn_cast<NullStmt>(Body); |
13326 | if (!NBody) |
13327 | return; |
13328 | |
13329 | |
13330 | if (!ShouldDiagnoseEmptyStmtBody(SourceMgr, StmtLoc, NBody)) |
13331 | return; |
13332 | |
13333 | Diag(NBody->getSemiLoc(), DiagID); |
13334 | Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line); |
13335 | } |
13336 | |
13337 | void Sema::DiagnoseEmptyLoopBody(const Stmt *S, |
13338 | const Stmt *PossibleBody) { |
13339 | assert(!CurrentInstantiationScope); |
13340 | |
13341 | SourceLocation StmtLoc; |
13342 | const Stmt *Body; |
13343 | unsigned DiagID; |
13344 | if (const ForStmt *FS = dyn_cast<ForStmt>(S)) { |
13345 | StmtLoc = FS->getRParenLoc(); |
13346 | Body = FS->getBody(); |
13347 | DiagID = diag::warn_empty_for_body; |
13348 | } else if (const WhileStmt *WS = dyn_cast<WhileStmt>(S)) { |
13349 | StmtLoc = WS->getCond()->getSourceRange().getEnd(); |
13350 | Body = WS->getBody(); |
13351 | DiagID = diag::warn_empty_while_body; |
13352 | } else |
13353 | return; |
13354 | |
13355 | |
13356 | const NullStmt *NBody = dyn_cast<NullStmt>(Body); |
13357 | if (!NBody) |
13358 | return; |
13359 | |
13360 | |
13361 | if (Diags.isIgnored(DiagID, NBody->getSemiLoc())) |
13362 | return; |
13363 | |
13364 | |
13365 | if (!ShouldDiagnoseEmptyStmtBody(SourceMgr, StmtLoc, NBody)) |
13366 | return; |
13367 | |
13368 | |
13369 | |
13370 | |
13371 | |
13372 | |
13373 | |
13374 | |
13375 | |
13376 | |
13377 | |
13378 | |
13379 | bool ProbableTypo = isa<CompoundStmt>(PossibleBody); |
13380 | if (!ProbableTypo) { |
13381 | bool BodyColInvalid; |
13382 | unsigned BodyCol = SourceMgr.getPresumedColumnNumber( |
13383 | PossibleBody->getBeginLoc(), &BodyColInvalid); |
13384 | if (BodyColInvalid) |
13385 | return; |
13386 | |
13387 | bool StmtColInvalid; |
13388 | unsigned StmtCol = |
13389 | SourceMgr.getPresumedColumnNumber(S->getBeginLoc(), &StmtColInvalid); |
13390 | if (StmtColInvalid) |
13391 | return; |
13392 | |
13393 | if (BodyCol > StmtCol) |
13394 | ProbableTypo = true; |
13395 | } |
13396 | |
13397 | if (ProbableTypo) { |
13398 | Diag(NBody->getSemiLoc(), DiagID); |
13399 | Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line); |
13400 | } |
13401 | } |
13402 | |
13403 | |
13404 | |
13405 | |
13406 | void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, |
13407 | SourceLocation OpLoc) { |
13408 | if (Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc)) |
13409 | return; |
13410 | |
13411 | if (inTemplateInstantiation()) |
13412 | return; |
13413 | |
13414 | |
13415 | LHSExpr = LHSExpr->IgnoreParenImpCasts(); |
13416 | RHSExpr = RHSExpr->IgnoreParenImpCasts(); |
13417 | |
13418 | |
13419 | const CallExpr *CE = dyn_cast<CallExpr>(RHSExpr); |
13420 | if (!CE || CE->getNumArgs() != 1) |
13421 | return; |
13422 | |
13423 | |
13424 | if (!CE->isCallToStdMove()) |
13425 | return; |
13426 | |
13427 | |
13428 | RHSExpr = CE->getArg(0); |
13429 | |
13430 | const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr); |
13431 | const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr); |
13432 | |
13433 | |
13434 | if (LHSDeclRef && RHSDeclRef) { |
13435 | if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl()) |
13436 | return; |
13437 | if (LHSDeclRef->getDecl()->getCanonicalDecl() != |
13438 | RHSDeclRef->getDecl()->getCanonicalDecl()) |
13439 | return; |
13440 | |
13441 | Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() |
13442 | << LHSExpr->getSourceRange() |
13443 | << RHSExpr->getSourceRange(); |
13444 | return; |
13445 | } |
13446 | |
13447 | |
13448 | |
13449 | |
13450 | |
13451 | const Expr *LHSBase = LHSExpr; |
13452 | const Expr *RHSBase = RHSExpr; |
13453 | const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr); |
13454 | const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr); |
13455 | if (!LHSME || !RHSME) |
13456 | return; |
13457 | |
13458 | while (LHSME && RHSME) { |
13459 | if (LHSME->getMemberDecl()->getCanonicalDecl() != |
13460 | RHSME->getMemberDecl()->getCanonicalDecl()) |
13461 | return; |
13462 | |
13463 | LHSBase = LHSME->getBase(); |
13464 | RHSBase = RHSME->getBase(); |
13465 | LHSME = dyn_cast<MemberExpr>(LHSBase); |
13466 | RHSME = dyn_cast<MemberExpr>(RHSBase); |
13467 | } |
13468 | |
13469 | LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase); |
13470 | RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase); |
13471 | if (LHSDeclRef && RHSDeclRef) { |
13472 | if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl()) |
13473 | return; |
13474 | if (LHSDeclRef->getDecl()->getCanonicalDecl() != |
13475 | RHSDeclRef->getDecl()->getCanonicalDecl()) |
13476 | return; |
13477 | |
13478 | Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() |
13479 | << LHSExpr->getSourceRange() |
13480 | << RHSExpr->getSourceRange(); |
13481 | return; |
13482 | } |
13483 | |
13484 | if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase)) |
13485 | Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() |
13486 | << LHSExpr->getSourceRange() |
13487 | << RHSExpr->getSourceRange(); |
13488 | } |
13489 | |
13490 | |
13491 | |
13492 | static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2); |
13493 | |
13494 | |
13495 | static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) { |
13496 | |
13497 | |
13498 | |
13499 | return ED1->isComplete() && ED2->isComplete() && |
13500 | C.hasSameType(ED1->getIntegerType(), ED2->getIntegerType()); |
13501 | } |
13502 | |
13503 | |
13504 | static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, |
13505 | FieldDecl *Field2) { |
13506 | if (!isLayoutCompatible(C, Field1->getType(), Field2->getType())) |
13507 | return false; |
13508 | |
13509 | if (Field1->isBitField() != Field2->isBitField()) |
13510 | return false; |
13511 | |
13512 | if (Field1->isBitField()) { |
13513 | |
13514 | unsigned Bits1 = Field1->getBitWidthValue(C); |
13515 | unsigned Bits2 = Field2->getBitWidthValue(C); |
13516 | |
13517 | if (Bits1 != Bits2) |
13518 | return false; |
13519 | } |
13520 | |
13521 | return true; |
13522 | } |
13523 | |
13524 | |
13525 | |
13526 | static bool isLayoutCompatibleStruct(ASTContext &C, RecordDecl *RD1, |
13527 | RecordDecl *RD2) { |
13528 | |
13529 | if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) { |
13530 | |
13531 | |
13532 | const CXXRecordDecl *D2CXX = cast<CXXRecordDecl>(RD2); |
13533 | |
13534 | if (D1CXX->getNumBases() != D2CXX->getNumBases()) |
13535 | return false; |
13536 | |
13537 | |
13538 | for (CXXRecordDecl::base_class_const_iterator |
13539 | Base1 = D1CXX->bases_begin(), |
13540 | BaseEnd1 = D1CXX->bases_end(), |
13541 | Base2 = D2CXX->bases_begin(); |
13542 | Base1 != BaseEnd1; |
13543 | ++Base1, ++Base2) { |
13544 | if (!isLayoutCompatible(C, Base1->getType(), Base2->getType())) |
13545 | return false; |
13546 | } |
13547 | } else if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) { |
13548 | |
13549 | if (D2CXX->getNumBases() > 0) |
13550 | return false; |
13551 | } |
13552 | |
13553 | |
13554 | RecordDecl::field_iterator Field2 = RD2->field_begin(), |
13555 | Field2End = RD2->field_end(), |
13556 | Field1 = RD1->field_begin(), |
13557 | Field1End = RD1->field_end(); |
13558 | for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) { |
13559 | if (!isLayoutCompatible(C, *Field1, *Field2)) |
13560 | return false; |
13561 | } |
13562 | if (Field1 != Field1End || Field2 != Field2End) |
13563 | return false; |
13564 | |
13565 | return true; |
13566 | } |
13567 | |
13568 | |
13569 | |
13570 | static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1, |
13571 | RecordDecl *RD2) { |
13572 | llvm::SmallPtrSet<FieldDecl *, 8> UnmatchedFields; |
13573 | for (auto *Field2 : RD2->fields()) |
13574 | UnmatchedFields.insert(Field2); |
13575 | |
13576 | for (auto *Field1 : RD1->fields()) { |
13577 | llvm::SmallPtrSet<FieldDecl *, 8>::iterator |
13578 | I = UnmatchedFields.begin(), |
13579 | E = UnmatchedFields.end(); |
13580 | |
13581 | for ( ; I != E; ++I) { |
13582 | if (isLayoutCompatible(C, Field1, *I)) { |
13583 | bool Result = UnmatchedFields.erase(*I); |
13584 | (void) Result; |
13585 | assert(Result); |
13586 | break; |
13587 | } |
13588 | } |
13589 | if (I == E) |
13590 | return false; |
13591 | } |
13592 | |
13593 | return UnmatchedFields.empty(); |
13594 | } |
13595 | |
13596 | static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, |
13597 | RecordDecl *RD2) { |
13598 | if (RD1->isUnion() != RD2->isUnion()) |
13599 | return false; |
13600 | |
13601 | if (RD1->isUnion()) |
13602 | return isLayoutCompatibleUnion(C, RD1, RD2); |
13603 | else |
13604 | return isLayoutCompatibleStruct(C, RD1, RD2); |
13605 | } |
13606 | |
13607 | |
13608 | static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) { |
13609 | if (T1.isNull() || T2.isNull()) |
13610 | return false; |
13611 | |
13612 | |
13613 | |
13614 | |
13615 | if (C.hasSameType(T1, T2)) |
13616 | return true; |
13617 | |
13618 | T1 = T1.getCanonicalType().getUnqualifiedType(); |
13619 | T2 = T2.getCanonicalType().getUnqualifiedType(); |
13620 | |
13621 | const Type::TypeClass TC1 = T1->getTypeClass(); |
13622 | const Type::TypeClass TC2 = T2->getTypeClass(); |
13623 | |
13624 | if (TC1 != TC2) |
13625 | return false; |
13626 | |
13627 | if (TC1 == Type::Enum) { |
13628 | return isLayoutCompatible(C, |
13629 | cast<EnumType>(T1)->getDecl(), |
13630 | cast<EnumType>(T2)->getDecl()); |
13631 | } else if (TC1 == Type::Record) { |
13632 | if (!T1->isStandardLayoutType() || !T2->isStandardLayoutType()) |
13633 | return false; |
13634 | |
13635 | return isLayoutCompatible(C, |
13636 | cast<RecordType>(T1)->getDecl(), |
13637 | cast<RecordType>(T2)->getDecl()); |
13638 | } |
13639 | |
13640 | return false; |
13641 | } |
13642 | |
13643 | |
13644 | |
13645 | |
13646 | |
13647 | |
13648 | |
13649 | |
13650 | |
13651 | |
13652 | static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, |
13653 | const ValueDecl **VD, uint64_t *MagicValue) { |
13654 | while(true) { |
13655 | if (!TypeExpr) |
13656 | return false; |
13657 | |
13658 | TypeExpr = TypeExpr->IgnoreParenImpCasts()->IgnoreParenCasts(); |
13659 | |
13660 | switch (TypeExpr->getStmtClass()) { |
13661 | case Stmt::UnaryOperatorClass: { |
13662 | const UnaryOperator *UO = cast<UnaryOperator>(TypeExpr); |
13663 | if (UO->getOpcode() == UO_AddrOf || UO->getOpcode() == UO_Deref) { |
13664 | TypeExpr = UO->getSubExpr(); |
13665 | continue; |
13666 | } |
13667 | return false; |
13668 | } |
13669 | |
13670 | case Stmt::DeclRefExprClass: { |
13671 | const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr); |
13672 | *VD = DRE->getDecl(); |
13673 | return true; |
13674 | } |
13675 | |
13676 | case Stmt::IntegerLiteralClass: { |
13677 | const IntegerLiteral *IL = cast<IntegerLiteral>(TypeExpr); |
13678 | llvm::APInt MagicValueAPInt = IL->getValue(); |
13679 | if (MagicValueAPInt.getActiveBits() <= 64) { |
13680 | *MagicValue = MagicValueAPInt.getZExtValue(); |
13681 | return true; |
13682 | } else |
13683 | return false; |
13684 | } |
13685 | |
13686 | case Stmt::BinaryConditionalOperatorClass: |
13687 | case Stmt::ConditionalOperatorClass: { |
13688 | const AbstractConditionalOperator *ACO = |
13689 | cast<AbstractConditionalOperator>(TypeExpr); |
13690 | bool Result; |
13691 | if (ACO->getCond()->EvaluateAsBooleanCondition(Result, Ctx)) { |
13692 | if (Result) |
13693 | TypeExpr = ACO->getTrueExpr(); |
13694 | else |
13695 | TypeExpr = ACO->getFalseExpr(); |
13696 | continue; |
13697 | } |
13698 | return false; |
13699 | } |
13700 | |
13701 | case Stmt::BinaryOperatorClass: { |
13702 | const BinaryOperator *BO = cast<BinaryOperator>(TypeExpr); |
13703 | if (BO->getOpcode() == BO_Comma) { |
13704 | TypeExpr = BO->getRHS(); |
13705 | continue; |
13706 | } |
13707 | return false; |
13708 | } |
13709 | |
13710 | default: |
13711 | return false; |
13712 | } |
13713 | } |
13714 | } |
13715 | |
13716 | |
13717 | |
13718 | |
13719 | |
13720 | |
13721 | |
13722 | |
13723 | |
13724 | |
13725 | |
13726 | |
13727 | |
13728 | static bool GetMatchingCType( |
13729 | const IdentifierInfo *ArgumentKind, |
13730 | const Expr *TypeExpr, const ASTContext &Ctx, |
13731 | const llvm::DenseMap<Sema::TypeTagMagicValue, |
13732 | Sema::TypeTagData> *MagicValues, |
13733 | bool &FoundWrongKind, |
13734 | Sema::TypeTagData &TypeInfo) { |
13735 | FoundWrongKind = false; |
13736 | |
13737 | |
13738 | const ValueDecl *VD = nullptr; |
13739 | |
13740 | uint64_t MagicValue; |
13741 | |
13742 | if (!FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue)) |
13743 | return false; |
13744 | |
13745 | if (VD) { |
13746 | if (TypeTagForDatatypeAttr *I = VD->getAttr<TypeTagForDatatypeAttr>()) { |
13747 | if (I->getArgumentKind() != ArgumentKind) { |
13748 | FoundWrongKind = true; |
13749 | return false; |
13750 | } |
13751 | TypeInfo.Type = I->getMatchingCType(); |
13752 | TypeInfo.LayoutCompatible = I->getLayoutCompatible(); |
13753 | TypeInfo.MustBeNull = I->getMustBeNull(); |
13754 | return true; |
13755 | } |
13756 | return false; |
13757 | } |
13758 | |
13759 | if (!MagicValues) |
13760 | return false; |
13761 | |
13762 | llvm::DenseMap<Sema::TypeTagMagicValue, |
13763 | Sema::TypeTagData>::const_iterator I = |
13764 | MagicValues->find(std::make_pair(ArgumentKind, MagicValue)); |
13765 | if (I == MagicValues->end()) |
13766 | return false; |
13767 | |
13768 | TypeInfo = I->second; |
13769 | return true; |
13770 | } |
13771 | |
13772 | void Sema::RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, |
13773 | uint64_t MagicValue, QualType Type, |
13774 | bool LayoutCompatible, |
13775 | bool MustBeNull) { |
13776 | if (!TypeTagForDatatypeMagicValues) |
13777 | TypeTagForDatatypeMagicValues.reset( |
13778 | new llvm::DenseMap<TypeTagMagicValue, TypeTagData>); |
13779 | |
13780 | TypeTagMagicValue Magic(ArgumentKind, MagicValue); |
13781 | (*TypeTagForDatatypeMagicValues)[Magic] = |
13782 | TypeTagData(Type, LayoutCompatible, MustBeNull); |
13783 | } |
13784 | |
13785 | static bool IsSameCharType(QualType T1, QualType T2) { |
13786 | const BuiltinType *BT1 = T1->getAs<BuiltinType>(); |
13787 | if (!BT1) |
13788 | return false; |
13789 | |
13790 | const BuiltinType *BT2 = T2->getAs<BuiltinType>(); |
13791 | if (!BT2) |
13792 | return false; |
13793 | |
13794 | BuiltinType::Kind T1Kind = BT1->getKind(); |
13795 | BuiltinType::Kind T2Kind = BT2->getKind(); |
13796 | |
13797 | return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) || |
13798 | (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) || |
13799 | (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) || |
13800 | (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar); |
13801 | } |
13802 | |
13803 | void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, |
13804 | const ArrayRef<const Expr *> ExprArgs, |
13805 | SourceLocation CallSiteLoc) { |
13806 | const IdentifierInfo *ArgumentKind = Attr->getArgumentKind(); |
13807 | bool IsPointerAttr = Attr->getIsPointer(); |
13808 | |
13809 | |
13810 | unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex(); |
13811 | if (TypeTagIdxAST >= ExprArgs.size()) { |
13812 | Diag(CallSiteLoc, diag::err_tag_index_out_of_range) |
13813 | << 0 << Attr->getTypeTagIdx().getSourceIndex(); |
13814 | return; |
13815 | } |
13816 | const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST]; |
13817 | bool FoundWrongKind; |
13818 | TypeTagData TypeInfo; |
13819 | if (!GetMatchingCType(ArgumentKind, TypeTagExpr, Context, |
13820 | TypeTagForDatatypeMagicValues.get(), |
13821 | FoundWrongKind, TypeInfo)) { |
13822 | if (FoundWrongKind) |
13823 | Diag(TypeTagExpr->getExprLoc(), |
13824 | diag::warn_type_tag_for_datatype_wrong_kind) |
13825 | << TypeTagExpr->getSourceRange(); |
13826 | return; |
13827 | } |
13828 | |
13829 | |
13830 | unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex(); |
13831 | if (ArgumentIdxAST >= ExprArgs.size()) { |
13832 | Diag(CallSiteLoc, diag::err_tag_index_out_of_range) |
13833 | << 1 << Attr->getArgumentIdx().getSourceIndex(); |
13834 | return; |
13835 | } |
13836 | const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST]; |
13837 | if (IsPointerAttr) { |
13838 | |
13839 | if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr)) |
13840 | if (ICE->getType()->isVoidPointerType() && |
13841 | ICE->getCastKind() == CK_BitCast) |
13842 | ArgumentExpr = ICE->getSubExpr(); |
13843 | } |
13844 | QualType ArgumentType = ArgumentExpr->getType(); |
13845 | |
13846 | |
13847 | if (IsPointerAttr && ArgumentType->isVoidPointerType()) |
13848 | return; |
13849 | |
13850 | if (TypeInfo.MustBeNull) { |
13851 | |
13852 | if (!ArgumentExpr->isNullPointerConstant(Context, |
13853 | Expr::NPC_ValueDependentIsNotNull)) { |
13854 | Diag(ArgumentExpr->getExprLoc(), |
13855 | diag::warn_type_safety_null_pointer_required) |
13856 | << ArgumentKind->getName() |
13857 | << ArgumentExpr->getSourceRange() |
13858 | << TypeTagExpr->getSourceRange(); |
13859 | } |
13860 | return; |
13861 | } |
13862 | |
13863 | QualType RequiredType = TypeInfo.Type; |
13864 | if (IsPointerAttr) |
13865 | RequiredType = Context.getPointerType(RequiredType); |
13866 | |
13867 | bool mismatch = false; |
13868 | if (!TypeInfo.LayoutCompatible) { |
13869 | mismatch = !Context.hasSameType(ArgumentType, RequiredType); |
13870 | |
13871 | |
13872 | |
13873 | |
13874 | |
13875 | |
13876 | if (mismatch) |
13877 | if ((IsPointerAttr && IsSameCharType(ArgumentType->getPointeeType(), |
13878 | RequiredType->getPointeeType())) || |
13879 | (!IsPointerAttr && IsSameCharType(ArgumentType, RequiredType))) |
13880 | mismatch = false; |
13881 | } else |
13882 | if (IsPointerAttr) |
13883 | mismatch = !isLayoutCompatible(Context, |
13884 | ArgumentType->getPointeeType(), |
13885 | RequiredType->getPointeeType()); |
13886 | else |
13887 | mismatch = !isLayoutCompatible(Context, ArgumentType, RequiredType); |
13888 | |
13889 | if (mismatch) |
13890 | Diag(ArgumentExpr->getExprLoc(), diag::warn_type_safety_type_mismatch) |
13891 | << ArgumentType << ArgumentKind |
13892 | << TypeInfo.LayoutCompatible << RequiredType |
13893 | << ArgumentExpr->getSourceRange() |
13894 | << TypeTagExpr->getSourceRange(); |
13895 | } |
13896 | |
13897 | void Sema::AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, |
13898 | CharUnits Alignment) { |
13899 | MisalignedMembers.emplace_back(E, RD, MD, Alignment); |
13900 | } |
13901 | |
13902 | void Sema::DiagnoseMisalignedMembers() { |
13903 | for (MisalignedMember &m : MisalignedMembers) { |
13904 | const NamedDecl *ND = m.RD; |
13905 | if (ND->getName().empty()) { |
13906 | if (const TypedefNameDecl *TD = m.RD->getTypedefNameForAnonDecl()) |
13907 | ND = TD; |
13908 | } |
13909 | Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member) |
13910 | << m.MD << ND << m.E->getSourceRange(); |
13911 | } |
13912 | MisalignedMembers.clear(); |
13913 | } |
13914 | |
13915 | void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) { |
13916 | E = E->IgnoreParens(); |
13917 | if (!T->isPointerType() && !T->isIntegerType()) |
13918 | return; |
13919 | if (isa<UnaryOperator>(E) && |
13920 | cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf) { |
13921 | auto *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens(); |
13922 | if (isa<MemberExpr>(Op)) { |
13923 | auto MA = std::find(MisalignedMembers.begin(), MisalignedMembers.end(), |
13924 | MisalignedMember(Op)); |
13925 | if (MA != MisalignedMembers.end() && |
13926 | (T->isIntegerType() || |
13927 | (T->isPointerType() && (T->getPointeeType()->isIncompleteType() || |
13928 | Context.getTypeAlignInChars( |
13929 | T->getPointeeType()) <= MA->Alignment)))) |
13930 | MisalignedMembers.erase(MA); |
13931 | } |
13932 | } |
13933 | } |
13934 | |
13935 | void Sema::RefersToMemberWithReducedAlignment( |
13936 | Expr *E, |
13937 | llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> |
13938 | Action) { |
13939 | const auto *ME = dyn_cast<MemberExpr>(E); |
13940 | if (!ME) |
13941 | return; |
13942 | |
13943 | |
13944 | if (E->getType().getQualifiers().hasUnaligned()) |
13945 | return; |
13946 | |
13947 | |
13948 | |
13949 | SmallVector<FieldDecl *, 4> ReverseMemberChain; |
13950 | const MemberExpr *TopME = nullptr; |
13951 | bool AnyIsPacked = false; |
13952 | do { |
13953 | QualType BaseType = ME->getBase()->getType(); |
13954 | if (ME->isArrow()) |
13955 | BaseType = BaseType->getPointeeType(); |
13956 | RecordDecl *RD = BaseType->getAs<RecordType>()->getDecl(); |
13957 | if (RD->isInvalidDecl()) |
13958 | return; |
13959 | |
13960 | ValueDecl *MD = ME->getMemberDecl(); |
13961 | auto *FD = dyn_cast<FieldDecl>(MD); |
13962 | |
13963 | if (!FD || FD->isInvalidDecl()) |
13964 | return; |
13965 | |
13966 | AnyIsPacked = |
13967 | AnyIsPacked || (RD->hasAttr<PackedAttr>() || MD->hasAttr<PackedAttr>()); |
13968 | ReverseMemberChain.push_back(FD); |
13969 | |
13970 | TopME = ME; |
13971 | ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens()); |
13972 | } while (ME); |
13973 | (0) . __assert_fail ("TopME && \"We did not compute a topmost MemberExpr!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 13973, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(TopME && "We did not compute a topmost MemberExpr!"); |
13974 | |
13975 | |
13976 | if (!AnyIsPacked) |
13977 | return; |
13978 | |
13979 | const Expr *TopBase = TopME->getBase()->IgnoreParenImpCasts(); |
13980 | const auto *DRE = dyn_cast<DeclRefExpr>(TopBase); |
13981 | |
13982 | |
13983 | |
13984 | if (!DRE && !isa<CXXThisExpr>(TopBase)) |
13985 | return; |
13986 | |
13987 | |
13988 | CharUnits ExpectedAlignment = Context.getTypeAlignInChars(E->getType()); |
13989 | |
13990 | |
13991 | if (ExpectedAlignment.isOne()) |
13992 | return; |
13993 | |
13994 | |
13995 | CharUnits Offset; |
13996 | for (auto I = ReverseMemberChain.rbegin(); I != ReverseMemberChain.rend(); |
13997 | I++) { |
13998 | Offset += Context.toCharUnitsFromBits(Context.getFieldOffset(*I)); |
13999 | } |
14000 | |
14001 | |
14002 | CharUnits CompleteObjectAlignment = Context.getTypeAlignInChars( |
14003 | ReverseMemberChain.back()->getParent()->getTypeForDecl()); |
14004 | |
14005 | |
14006 | |
14007 | if (DRE && !TopME->isArrow()) { |
14008 | const ValueDecl *VD = DRE->getDecl(); |
14009 | if (!VD->getType()->isReferenceType()) |
14010 | CompleteObjectAlignment = |
14011 | std::max(CompleteObjectAlignment, Context.getDeclAlign(VD)); |
14012 | } |
14013 | |
14014 | |
14015 | if (Offset % ExpectedAlignment != 0 || |
14016 | |
14017 | |
14018 | CompleteObjectAlignment < ExpectedAlignment) { |
14019 | |
14020 | |
14021 | |
14022 | |
14023 | |
14024 | |
14025 | |
14026 | |
14027 | FieldDecl *FD = nullptr; |
14028 | CharUnits Alignment; |
14029 | for (FieldDecl *FDI : ReverseMemberChain) { |
14030 | if (FDI->hasAttr<PackedAttr>() || |
14031 | FDI->getParent()->hasAttr<PackedAttr>()) { |
14032 | FD = FDI; |
14033 | Alignment = std::min( |
14034 | Context.getTypeAlignInChars(FD->getType()), |
14035 | Context.getTypeAlignInChars(FD->getParent()->getTypeForDecl())); |
14036 | break; |
14037 | } |
14038 | } |
14039 | (0) . __assert_fail ("FD && \"We did not find a packed FieldDecl!\"", "/home/seafit/code_projects/clang_source/clang/lib/Sema/SemaChecking.cpp", 14039, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(FD && "We did not find a packed FieldDecl!"); |
14040 | Action(E, FD->getParent(), FD, Alignment); |
14041 | } |
14042 | } |
14043 | |
14044 | void Sema::CheckAddressOfPackedMember(Expr *rhs) { |
14045 | using namespace std::placeholders; |
14046 | |
14047 | RefersToMemberWithReducedAlignment( |
14048 | rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*this), _1, |
14049 | _2, _3, _4)); |
14050 | } |
14051 | |