81 #include "llvm/ADT/APFloat.h"
82 #include "llvm/ADT/APInt.h"
83 #include "llvm/ADT/APSInt.h"
84 #include "llvm/ADT/ArrayRef.h"
85 #include "llvm/ADT/DenseMap.h"
86 #include "llvm/ADT/FoldingSet.h"
87 #include "llvm/ADT/STLExtras.h"
88 #include "llvm/ADT/SmallBitVector.h"
89 #include "llvm/ADT/SmallPtrSet.h"
90 #include "llvm/ADT/SmallString.h"
91 #include "llvm/ADT/SmallVector.h"
92 #include "llvm/ADT/StringExtras.h"
93 #include "llvm/ADT/StringRef.h"
94 #include "llvm/ADT/StringSet.h"
95 #include "llvm/ADT/StringSwitch.h"
96 #include "llvm/Support/AtomicOrdering.h"
97 #include "llvm/Support/Casting.h"
98 #include "llvm/Support/Compiler.h"
99 #include "llvm/Support/ConvertUTF.h"
100 #include "llvm/Support/ErrorHandling.h"
101 #include "llvm/Support/Format.h"
102 #include "llvm/Support/Locale.h"
103 #include "llvm/Support/MathExtras.h"
104 #include "llvm/Support/SaveAndRestore.h"
105 #include "llvm/Support/raw_ostream.h"
106 #include "llvm/TargetParser/RISCVTargetParser.h"
107 #include "llvm/TargetParser/Triple.h"
114 #include <functional>
121 using namespace clang;
122 using namespace sema;
128 unsigned ByteNo)
const {
139 unsigned ArgCount = Call->getNumArgs();
140 if (ArgCount >= MinArgCount)
143 return Diag(Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
144 << 0 << MinArgCount << ArgCount
145 << 0 << Call->getSourceRange();
149 unsigned ArgCount = Call->getNumArgs();
150 if (ArgCount <= MaxArgCount)
152 return Diag(Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
153 << 0 << MaxArgCount << ArgCount
154 << 0 << Call->getSourceRange();
158 unsigned MaxArgCount) {
159 return checkArgCountAtLeast(Call, MinArgCount) ||
160 checkArgCountAtMost(Call, MaxArgCount);
164 unsigned ArgCount = Call->getNumArgs();
165 if (ArgCount == DesiredArgCount)
168 if (checkArgCountAtLeast(Call, DesiredArgCount))
170 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
174 Call->getArg(ArgCount - 1)->getEndLoc());
177 << 0 << DesiredArgCount << ArgCount
178 << 0 << Call->getArg(1)->getSourceRange();
182 bool HasError =
false;
184 for (
unsigned I = 0; I < Call->getNumArgs(); ++I) {
185 Expr *Arg = Call->getArg(I);
191 int DiagMsgKind = -1;
193 if (!ArgString.has_value())
195 else if (ArgString->find(
'$') != std::string::npos)
198 if (DiagMsgKind >= 0) {
209 if (
Value->isTypeDependent())
216 if (Result.isInvalid())
218 Value = Result.get();
253 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
261 auto *
Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
263 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
264 << Arg->getSourceRange();
298 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
329 bool IsBooleanAlignBuiltin =
ID == Builtin::BI__builtin_is_aligned;
331 auto IsValidIntegerType = [](
QualType Ty) {
332 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
339 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
343 S.
Diag(Source->
getExprLoc(), diag::err_typecheck_expect_scalar_operand)
349 if (!IsValidIntegerType(AlignOp->
getType())) {
362 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
363 if (AlignValue < 1) {
364 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
367 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
372 if (!AlignValue.isPowerOf2()) {
373 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
376 if (AlignValue == 1) {
377 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
378 << IsBooleanAlignBuiltin;
406 std::pair<unsigned, const char *> Builtins[] = {
407 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
408 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
409 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
412 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
414 return BuiltinID ==
P.first && TheCall->
getExprLoc().isMacroID() &&
419 auto ValidCkdIntType = [](
QualType QT) {
422 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
423 return (BT->getKind() >= BuiltinType::Short &&
424 BT->getKind() <= BuiltinType::Int128) || (
425 BT->getKind() >= BuiltinType::UShort &&
426 BT->getKind() <= BuiltinType::UInt128) ||
427 BT->getKind() == BuiltinType::UChar ||
428 BT->getKind() == BuiltinType::SChar;
433 for (
unsigned I = 0; I < 2; ++I) {
439 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
458 !PtrTy->getPointeeType()->isIntegerType() ||
459 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
460 PtrTy->getPointeeType().isConstQualified()) {
462 diag::err_overflow_builtin_must_be_ptr_int)
470 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
471 for (
unsigned I = 0; I < 3; ++I) {
472 const auto Arg = TheCall->
getArg(I);
475 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
477 return S.
Diag(Arg->getBeginLoc(),
478 diag::err_overflow_builtin_bit_int_max_size)
487 struct BuiltinDumpStructGenerator {
496 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
497 Policy(S.Context.getPrintingPolicy()) {
501 Expr *makeOpaqueValueExpr(
Expr *Inner) {
504 Inner->getObjectKind(), Inner);
505 Actions.push_back(OVE);
509 Expr *getStringLiteral(llvm::StringRef Str) {
515 bool callPrintFunction(llvm::StringRef Format,
519 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
521 Args.push_back(getStringLiteral(Format));
522 Args.insert(Args.end(), Exprs.begin(), Exprs.end());
538 Actions.push_back(RealCall.
get());
550 return getStringLiteral(
Indent);
554 return getStringLiteral(
T.getAsString(Policy));
558 llvm::raw_svector_ostream OS(Str);
563 switch (BT->getKind()) {
564 case BuiltinType::Bool:
567 case BuiltinType::Char_U:
568 case BuiltinType::UChar:
571 case BuiltinType::Char_S:
572 case BuiltinType::SChar:
590 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
611 Expr *IndentLit = getIndentString(
Depth);
613 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
614 : callPrintFunction(
"%s", {TypeLit}))
617 return dumpRecordValue(RD,
E, IndentLit,
Depth);
630 Expr *RecordArg = makeOpaqueValueExpr(
E);
633 if (callPrintFunction(
" {\n"))
637 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
638 for (
const auto &
Base : CXXRD->bases()) {
646 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
652 Expr *FieldIndentArg = getIndentString(
Depth + 1);
655 for (
auto *
D : RD->
decls()) {
656 auto *IFD = dyn_cast<IndirectFieldDecl>(
D);
657 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(
D);
658 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
664 getStringLiteral(FD->getName())};
666 if (FD->isBitField()) {
670 FD->getBitWidthValue(S.
Context));
684 if (
Field.isInvalid())
687 auto *InnerRD = FD->getType()->getAsRecordDecl();
688 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
689 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
691 if (callPrintFunction(Format, Args) ||
692 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg,
Depth + 1))
696 if (appendFormatSpecifier(FD->getType(), Format)) {
698 Args.push_back(
Field.get());
708 Args.push_back(FieldAddr.
get());
711 if (callPrintFunction(Format, Args))
716 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
717 : callPrintFunction(
"}\n");
720 Expr *buildWrapper() {
723 TheCall->
setType(Wrapper->getType());
744 diag::err_expected_struct_pointer_argument)
753 diag::err_incomplete_type))
762 switch (BT ? BT->getKind() : BuiltinType::Void) {
763 case BuiltinType::Dependent:
764 case BuiltinType::Overload:
765 case BuiltinType::BoundMember:
766 case BuiltinType::PseudoObject:
767 case BuiltinType::UnknownAny:
768 case BuiltinType::BuiltinFn:
774 diag::err_expected_callable_argument)
780 BuiltinDumpStructGenerator
Generator(S, TheCall);
786 Expr *PtrArg = PtrArgResult.
get();
790 if (
Generator.dumpUnnamedRecord(RD, PtrArg, 0))
805 if (Call->getStmtClass() != Stmt::CallExprClass) {
806 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
807 << Call->getSourceRange();
811 auto CE = cast<CallExpr>(Call);
812 if (CE->getCallee()->getType()->isBlockPointerType()) {
813 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
814 << Call->getSourceRange();
818 const Decl *TargetDecl = CE->getCalleeDecl();
819 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
820 if (FD->getBuiltinID()) {
821 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
822 << Call->getSourceRange();
826 if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {
827 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
828 << Call->getSourceRange();
836 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
850 BuiltinCall->
setType(CE->getType());
854 BuiltinCall->
setArg(1, ChainResult.
get());
861 class ScanfDiagnosticFormatHandler
865 using ComputeSizeFunction =
866 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
870 using DiagnoseFunction =
871 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
873 ComputeSizeFunction ComputeSizeArgument;
874 DiagnoseFunction Diagnose;
877 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
878 DiagnoseFunction Diagnose)
879 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
882 const char *StartSpecifier,
883 unsigned specifierLen)
override {
884 if (!FS.consumesDataArgument())
887 unsigned NulByte = 0;
888 switch ((FS.getConversionSpecifier().getKind())) {
901 analyze_format_string::OptionalAmount::HowSpecified::Constant)
906 std::optional<llvm::APSInt> DestSizeAPS =
907 ComputeSizeArgument(FS.getArgIndex());
911 unsigned DestSize = DestSizeAPS->getZExtValue();
913 if (DestSize < SourceSize)
914 Diagnose(FS.getArgIndex(), DestSize, SourceSize);
920 class EstimateSizeFormatHandler
925 bool IsKernelCompatible =
true;
928 EstimateSizeFormatHandler(StringRef Format)
929 :
Size(
std::
min(Format.find(0), Format.size()) +
933 const char *,
unsigned SpecifierLen,
936 const size_t FieldWidth = computeFieldWidth(FS);
937 const size_t Precision = computePrecision(FS);
940 switch (FS.getConversionSpecifier().getKind()) {
973 (Precision ? 1 + Precision
983 (Precision ? 1 + Precision : 0) +
993 (Precision ? 1 + Precision : 0) +
1008 IsKernelCompatible =
false;
1021 Size += FS.hasPlusPrefix() || FS.hasSpacePrefix();
1023 if (FS.hasAlternativeForm()) {
1024 switch (FS.getConversionSpecifier().getKind()) {
1053 Size += (Precision ? 0 : 1);
1060 assert(SpecifierLen <= Size &&
"no underflow");
1061 Size -= SpecifierLen;
1065 size_t getSizeLowerBound()
const {
return Size; }
1066 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1071 size_t FieldWidth = 0;
1079 size_t Precision = 0;
1084 switch (FS.getConversionSpecifier().getKind()) {
1126 StringRef &FormatStrRef,
size_t &StrLen,
1128 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1129 Format && (Format->isOrdinary() || Format->isUTF8())) {
1130 FormatStrRef = Format->getString();
1133 assert(
T &&
"String literal not of constant array type!");
1134 size_t TypeSize =
T->getZExtSize();
1136 StrLen =
std::min(
std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1142 void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1145 isConstantEvaluatedContext())
1148 bool UseDABAttr =
false;
1151 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1153 UseDecl = DABAttr->getFunction();
1154 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1163 const TargetInfo &TI = getASTContext().getTargetInfo();
1166 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1173 unsigned DABIndices = DABAttr->argIndices_size();
1174 unsigned NewIndex = Index < DABIndices
1175 ? DABAttr->argIndices_begin()[Index]
1178 return std::nullopt;
1182 auto ComputeExplicitObjectSizeArgument =
1183 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1184 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1186 return std::nullopt;
1187 unsigned NewIndex = *IndexOptional;
1191 return std::nullopt;
1197 auto ComputeSizeArgument =
1198 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1204 if (Index < FD->getNumParams()) {
1205 if (
const auto *POS =
1207 BOSType = POS->getType();
1210 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1212 return std::nullopt;
1213 unsigned NewIndex = *IndexOptional;
1216 return std::nullopt;
1218 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1221 return std::nullopt;
1224 return llvm::APSInt::getUnsigned(Result).extOrTrunc(SizeTypeWidth);
1227 auto ComputeStrLenArgument =
1228 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1229 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1231 return std::nullopt;
1232 unsigned NewIndex = *IndexOptional;
1234 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1237 return std::nullopt;
1239 return llvm::APSInt::getUnsigned(Result + 1).extOrTrunc(SizeTypeWidth);
1242 std::optional<llvm::APSInt> SourceSize;
1243 std::optional<llvm::APSInt> DestinationSize;
1244 unsigned DiagID = 0;
1245 bool IsChkVariant =
false;
1247 auto GetFunctionName = [&]() {
1248 StringRef FunctionName = getASTContext().BuiltinInfo.getName(BuiltinID);
1253 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1254 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1256 FunctionName.consume_front(
"__builtin_");
1258 return FunctionName;
1261 switch (BuiltinID) {
1264 case Builtin::BI__builtin_strcpy:
1265 case Builtin::BIstrcpy: {
1266 DiagID = diag::warn_fortify_strlen_overflow;
1267 SourceSize = ComputeStrLenArgument(1);
1268 DestinationSize = ComputeSizeArgument(0);
1272 case Builtin::BI__builtin___strcpy_chk: {
1273 DiagID = diag::warn_fortify_strlen_overflow;
1274 SourceSize = ComputeStrLenArgument(1);
1275 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1276 IsChkVariant =
true;
1280 case Builtin::BIscanf:
1281 case Builtin::BIfscanf:
1282 case Builtin::BIsscanf: {
1283 unsigned FormatIndex = 1;
1284 unsigned DataIndex = 2;
1285 if (BuiltinID == Builtin::BIscanf) {
1290 const auto *FormatExpr =
1293 StringRef FormatStrRef;
1298 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1299 unsigned SourceSize) {
1300 DiagID = diag::warn_fortify_scanf_overflow;
1301 unsigned Index = ArgIndex + DataIndex;
1302 StringRef FunctionName = GetFunctionName();
1304 PDiag(DiagID) << FunctionName << (Index + 1)
1305 << DestSize << SourceSize);
1308 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1309 return ComputeSizeArgument(Index + DataIndex);
1311 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument, Diagnose);
1312 const char *FormatBytes = FormatStrRef.data();
1314 FormatBytes + StrLen, getLangOpts(),
1323 case Builtin::BIsprintf:
1324 case Builtin::BI__builtin___sprintf_chk: {
1325 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1328 StringRef FormatStrRef;
1331 EstimateSizeFormatHandler H(FormatStrRef);
1332 const char *FormatBytes = FormatStrRef.data();
1334 H, FormatBytes, FormatBytes + StrLen, getLangOpts(),
1336 DiagID = H.isKernelCompatible()
1337 ? diag::warn_format_overflow
1338 : diag::warn_format_overflow_non_kprintf;
1339 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1340 .extOrTrunc(SizeTypeWidth);
1341 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1342 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1343 IsChkVariant =
true;
1345 DestinationSize = ComputeSizeArgument(0);
1352 case Builtin::BI__builtin___memcpy_chk:
1353 case Builtin::BI__builtin___memmove_chk:
1354 case Builtin::BI__builtin___memset_chk:
1355 case Builtin::BI__builtin___strlcat_chk:
1356 case Builtin::BI__builtin___strlcpy_chk:
1357 case Builtin::BI__builtin___strncat_chk:
1358 case Builtin::BI__builtin___strncpy_chk:
1359 case Builtin::BI__builtin___stpncpy_chk:
1360 case Builtin::BI__builtin___memccpy_chk:
1361 case Builtin::BI__builtin___mempcpy_chk: {
1362 DiagID = diag::warn_builtin_chk_overflow;
1363 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1365 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1366 IsChkVariant =
true;
1370 case Builtin::BI__builtin___snprintf_chk:
1371 case Builtin::BI__builtin___vsnprintf_chk: {
1372 DiagID = diag::warn_builtin_chk_overflow;
1373 SourceSize = ComputeExplicitObjectSizeArgument(1);
1374 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1375 IsChkVariant =
true;
1379 case Builtin::BIstrncat:
1380 case Builtin::BI__builtin_strncat:
1381 case Builtin::BIstrncpy:
1382 case Builtin::BI__builtin_strncpy:
1383 case Builtin::BIstpncpy:
1384 case Builtin::BI__builtin_stpncpy: {
1390 DiagID = diag::warn_fortify_source_size_mismatch;
1391 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1392 DestinationSize = ComputeSizeArgument(0);
1396 case Builtin::BImemcpy:
1397 case Builtin::BI__builtin_memcpy:
1398 case Builtin::BImemmove:
1399 case Builtin::BI__builtin_memmove:
1400 case Builtin::BImemset:
1401 case Builtin::BI__builtin_memset:
1402 case Builtin::BImempcpy:
1403 case Builtin::BI__builtin_mempcpy: {
1404 DiagID = diag::warn_fortify_source_overflow;
1405 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1406 DestinationSize = ComputeSizeArgument(0);
1409 case Builtin::BIsnprintf:
1410 case Builtin::BI__builtin_snprintf:
1411 case Builtin::BIvsnprintf:
1412 case Builtin::BI__builtin_vsnprintf: {
1413 DiagID = diag::warn_fortify_source_size_mismatch;
1414 SourceSize = ComputeExplicitObjectSizeArgument(1);
1416 StringRef FormatStrRef;
1420 EstimateSizeFormatHandler H(FormatStrRef);
1421 const char *FormatBytes = FormatStrRef.data();
1423 H, FormatBytes, FormatBytes + StrLen, getLangOpts(),
1426 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1427 .extOrTrunc(SizeTypeWidth);
1428 if (FormatSize > *SourceSize && *SourceSize != 0) {
1429 unsigned TruncationDiagID =
1430 H.isKernelCompatible() ? diag::warn_format_truncation
1431 : diag::warn_format_truncation_non_kprintf;
1434 SourceSize->toString(SpecifiedSizeStr, 10);
1435 FormatSize.toString(FormatSizeStr, 10);
1436 DiagRuntimeBehavior(TheCall->
getBeginLoc(), TheCall,
1437 PDiag(TruncationDiagID)
1438 << GetFunctionName() << SpecifiedSizeStr
1443 DestinationSize = ComputeSizeArgument(0);
1447 if (!SourceSize || !DestinationSize ||
1448 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1451 StringRef FunctionName = GetFunctionName();
1455 DestinationSize->toString(DestinationStr, 10);
1456 SourceSize->toString(SourceStr, 10);
1457 DiagRuntimeBehavior(TheCall->
getBeginLoc(), TheCall,
1459 << FunctionName << DestinationStr << SourceStr);
1472 while (S && !S->isSEHExceptScope())
1474 if (!S || !(S->getFlags() & NeededScopeFlags)) {
1477 << DRE->getDecl()->getIdentifier();
1489 "__builtin_alloca has invalid address space");
1497 enum PointerAuthOpKind {
1509 if (getLangOpts().PointerAuthIntrinsics)
1546 llvm::raw_svector_ostream Str(
Value);
1555 Result = KeyValue->getZExtValue();
1559 static std::pair<const ValueDecl *, CharUnits>
1566 const auto *BaseDecl =
1567 Result.Val.getLValueBase().dyn_cast<
const ValueDecl *>();
1571 return {BaseDecl, Result.Val.getLValueOffset()};
1575 bool RequireConstant =
false) {
1583 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1584 return OpKind != PAO_BlendInteger;
1586 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1587 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1588 OpKind == PAO_SignGeneric;
1597 }
else if (AllowsInteger(OpKind) &&
1604 <<
unsigned(OpKind == PAO_Discriminator ? 1
1605 : OpKind == PAO_BlendPointer ? 2
1606 : OpKind == PAO_BlendInteger ? 3
1608 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1618 if (!RequireConstant) {
1620 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1623 ? diag::warn_ptrauth_sign_null_pointer
1624 : diag::warn_ptrauth_auth_null_pointer)
1634 if (OpKind == PAO_Sign) {
1644 else if (isa<FunctionDecl>(BaseDecl))
1645 Invalid = !
Offset.isZero();
1652 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1657 assert(OpKind == PAO_Discriminator);
1660 Expr *Pointer =
nullptr;
1662 if (
auto *Call = dyn_cast<CallExpr>(Arg->
IgnoreParens())) {
1663 if (Call->getBuiltinCallee() ==
1664 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1665 Pointer = Call->getArg(0);
1677 bool Invalid =
false;
1679 assert(Pointer->getType()->isPointerType());
1685 if (!BaseDecl || !isa<VarDecl>(BaseDecl))
1691 assert(
Integer->getType()->isIntegerType());
1697 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1710 Call->setType(Call->getArgs()[0]->getType());
1741 PointerAuthOpKind OpKind,
1742 bool RequireConstant) {
1753 Call->setType(Call->getArgs()[0]->getType());
1769 Call->setType(Call->getArgs()[0]->getType());
1778 const Expr *Arg = Call->getArg(0)->IgnoreParenImpCasts();
1781 const auto *
Literal = dyn_cast<StringLiteral>(Arg);
1812 auto DiagSelect = [&]() -> std::optional<unsigned> {
1819 return std::optional<unsigned>{};
1834 diag::err_incomplete_type))
1838 "Unhandled non-object pointer case");
1856 llvm::Triple::ObjectFormatType CurObjFormat =
1858 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
1871 llvm::Triple::ArchType CurArch =
1873 if (llvm::is_contained(SupportedArchs, CurArch))
1883 bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
1890 case llvm::Triple::arm:
1891 case llvm::Triple::armeb:
1892 case llvm::Triple::thumb:
1893 case llvm::Triple::thumbeb:
1894 return ARM().CheckARMBuiltinFunctionCall(TI, BuiltinID, TheCall);
1895 case llvm::Triple::aarch64:
1896 case llvm::Triple::aarch64_32:
1897 case llvm::Triple::aarch64_be:
1898 return ARM().CheckAArch64BuiltinFunctionCall(TI, BuiltinID, TheCall);
1899 case llvm::Triple::bpfeb:
1900 case llvm::Triple::bpfel:
1901 return BPF().CheckBPFBuiltinFunctionCall(BuiltinID, TheCall);
1902 case llvm::Triple::hexagon:
1903 return Hexagon().CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall);
1904 case llvm::Triple::mips:
1905 case llvm::Triple::mipsel:
1906 case llvm::Triple::mips64:
1907 case llvm::Triple::mips64el:
1908 return MIPS().CheckMipsBuiltinFunctionCall(TI, BuiltinID, TheCall);
1909 case llvm::Triple::systemz:
1910 return SystemZ().CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall);
1911 case llvm::Triple::x86:
1912 case llvm::Triple::x86_64:
1913 return X86().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall);
1914 case llvm::Triple::ppc:
1915 case llvm::Triple::ppcle:
1916 case llvm::Triple::ppc64:
1917 case llvm::Triple::ppc64le:
1918 return PPC().CheckPPCBuiltinFunctionCall(TI, BuiltinID, TheCall);
1919 case llvm::Triple::amdgcn:
1920 return AMDGPU().CheckAMDGCNBuiltinFunctionCall(BuiltinID, TheCall);
1921 case llvm::Triple::riscv32:
1922 case llvm::Triple::riscv64:
1923 return RISCV().CheckBuiltinFunctionCall(TI, BuiltinID, TheCall);
1924 case llvm::Triple::loongarch32:
1925 case llvm::Triple::loongarch64:
1926 return LoongArch().CheckLoongArchBuiltinFunctionCall(TI, BuiltinID,
1928 case llvm::Triple::wasm32:
1929 case llvm::Triple::wasm64:
1930 return Wasm().CheckWebAssemblyBuiltinFunctionCall(TI, BuiltinID, TheCall);
1931 case llvm::Triple::nvptx:
1932 case llvm::Triple::nvptx64:
1933 return NVPTX().CheckNVPTXBuiltinFunctionCall(TI, BuiltinID, TheCall);
1944 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1945 << ArgIndex << 0 << ArgTy;
1955 EltTy = VecTy->getElementType();
1958 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1959 << ArgIndex << 5 << ArgTy;
1969 const TargetInfo *AuxTI,
unsigned BuiltinID) {
1970 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
1971 BuiltinID == Builtin::BI__builtin_cpu_is) &&
1972 "Expecting __builtin_cpu_...");
1974 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
1976 auto SupportsBI = [=](
const TargetInfo *TInfo) {
1977 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
1978 (!IsCPUSupports && TInfo->supportsCpuIs()));
1980 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
1987 ? diag::err_builtin_aix_os_unsupported
1988 : diag::err_builtin_target_unsupported)
1993 if (!isa<StringLiteral>(Arg))
1994 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
1998 StringRef Feature = cast<StringLiteral>(Arg)->getString();
2045 TheCall->
setArg(0, Arg0);
2051 << 1 << 7 << Arg0Ty;
2061 TheCall->
setArg(1, Arg1);
2067 << 2 << 8 << Arg1Ty;
2076 Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2081 unsigned ICEArguments = 0;
2088 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2090 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2095 if (ArgNo < TheCall->getNumArgs() &&
2096 BuiltinConstantArg(TheCall, ArgNo, Result))
2098 ICEArguments &= ~(1 << ArgNo);
2102 switch (BuiltinID) {
2103 case Builtin::BI__builtin_cpu_supports:
2104 case Builtin::BI__builtin_cpu_is:
2109 case Builtin::BI__builtin_cpu_init:
2116 case Builtin::BI__builtin___CFStringMakeConstantString:
2120 *
this, BuiltinID, TheCall,
2121 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2124 "Wrong # arguments to builtin CFStringMakeConstantString");
2125 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2128 case Builtin::BI__builtin_ms_va_start:
2129 case Builtin::BI__builtin_stdarg_start:
2130 case Builtin::BI__builtin_va_start:
2131 if (BuiltinVAStart(BuiltinID, TheCall))
2134 case Builtin::BI__va_start: {
2136 case llvm::Triple::aarch64:
2137 case llvm::Triple::arm:
2138 case llvm::Triple::thumb:
2139 if (BuiltinVAStartARMMicrosoft(TheCall))
2143 if (BuiltinVAStart(BuiltinID, TheCall))
2151 case Builtin::BI_interlockedbittestandset_acq:
2152 case Builtin::BI_interlockedbittestandset_rel:
2153 case Builtin::BI_interlockedbittestandset_nf:
2154 case Builtin::BI_interlockedbittestandreset_acq:
2155 case Builtin::BI_interlockedbittestandreset_rel:
2156 case Builtin::BI_interlockedbittestandreset_nf:
2159 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2164 case Builtin::BI_bittest64:
2165 case Builtin::BI_bittestandcomplement64:
2166 case Builtin::BI_bittestandreset64:
2167 case Builtin::BI_bittestandset64:
2168 case Builtin::BI_interlockedbittestandreset64:
2169 case Builtin::BI_interlockedbittestandset64:
2172 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2173 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2177 case Builtin::BI__builtin_set_flt_rounds:
2180 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2181 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2185 case Builtin::BI__builtin_isgreater:
2186 case Builtin::BI__builtin_isgreaterequal:
2187 case Builtin::BI__builtin_isless:
2188 case Builtin::BI__builtin_islessequal:
2189 case Builtin::BI__builtin_islessgreater:
2190 case Builtin::BI__builtin_isunordered:
2191 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2194 case Builtin::BI__builtin_fpclassify:
2195 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2198 case Builtin::BI__builtin_isfpclass:
2199 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2202 case Builtin::BI__builtin_isfinite:
2203 case Builtin::BI__builtin_isinf:
2204 case Builtin::BI__builtin_isinf_sign:
2205 case Builtin::BI__builtin_isnan:
2206 case Builtin::BI__builtin_issignaling:
2207 case Builtin::BI__builtin_isnormal:
2208 case Builtin::BI__builtin_issubnormal:
2209 case Builtin::BI__builtin_iszero:
2210 case Builtin::BI__builtin_signbit:
2211 case Builtin::BI__builtin_signbitf:
2212 case Builtin::BI__builtin_signbitl:
2213 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2216 case Builtin::BI__builtin_shufflevector:
2217 return BuiltinShuffleVector(TheCall);
2220 case Builtin::BI__builtin_prefetch:
2221 if (BuiltinPrefetch(TheCall))
2224 case Builtin::BI__builtin_alloca_with_align:
2225 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2226 if (BuiltinAllocaWithAlign(TheCall))
2229 case Builtin::BI__builtin_alloca:
2230 case Builtin::BI__builtin_alloca_uninitialized:
2233 if (getLangOpts().OpenCL) {
2237 case Builtin::BI__arithmetic_fence:
2238 if (BuiltinArithmeticFence(TheCall))
2241 case Builtin::BI__assume:
2242 case Builtin::BI__builtin_assume:
2243 if (BuiltinAssume(TheCall))
2246 case Builtin::BI__builtin_assume_aligned:
2247 if (BuiltinAssumeAligned(TheCall))
2250 case Builtin::BI__builtin_dynamic_object_size:
2251 case Builtin::BI__builtin_object_size:
2252 if (BuiltinConstantArgRange(TheCall, 1, 0, 3))
2255 case Builtin::BI__builtin_longjmp:
2256 if (BuiltinLongjmp(TheCall))
2259 case Builtin::BI__builtin_setjmp:
2260 if (BuiltinSetjmp(TheCall))
2263 case Builtin::BI__builtin_classify_type:
2264 if (checkArgCount(TheCall, 1))
2268 case Builtin::BI__builtin_complex:
2269 if (BuiltinComplex(TheCall))
2272 case Builtin::BI__builtin_constant_p: {
2273 if (checkArgCount(TheCall, 1))
2281 case Builtin::BI__builtin_launder:
2283 case Builtin::BI__sync_fetch_and_add:
2284 case Builtin::BI__sync_fetch_and_add_1:
2285 case Builtin::BI__sync_fetch_and_add_2:
2286 case Builtin::BI__sync_fetch_and_add_4:
2287 case Builtin::BI__sync_fetch_and_add_8:
2288 case Builtin::BI__sync_fetch_and_add_16:
2289 case Builtin::BI__sync_fetch_and_sub:
2290 case Builtin::BI__sync_fetch_and_sub_1:
2291 case Builtin::BI__sync_fetch_and_sub_2:
2292 case Builtin::BI__sync_fetch_and_sub_4:
2293 case Builtin::BI__sync_fetch_and_sub_8:
2294 case Builtin::BI__sync_fetch_and_sub_16:
2295 case Builtin::BI__sync_fetch_and_or:
2296 case Builtin::BI__sync_fetch_and_or_1:
2297 case Builtin::BI__sync_fetch_and_or_2:
2298 case Builtin::BI__sync_fetch_and_or_4:
2299 case Builtin::BI__sync_fetch_and_or_8:
2300 case Builtin::BI__sync_fetch_and_or_16:
2301 case Builtin::BI__sync_fetch_and_and:
2302 case Builtin::BI__sync_fetch_and_and_1:
2303 case Builtin::BI__sync_fetch_and_and_2:
2304 case Builtin::BI__sync_fetch_and_and_4:
2305 case Builtin::BI__sync_fetch_and_and_8:
2306 case Builtin::BI__sync_fetch_and_and_16:
2307 case Builtin::BI__sync_fetch_and_xor:
2308 case Builtin::BI__sync_fetch_and_xor_1:
2309 case Builtin::BI__sync_fetch_and_xor_2:
2310 case Builtin::BI__sync_fetch_and_xor_4:
2311 case Builtin::BI__sync_fetch_and_xor_8:
2312 case Builtin::BI__sync_fetch_and_xor_16:
2313 case Builtin::BI__sync_fetch_and_nand:
2314 case Builtin::BI__sync_fetch_and_nand_1:
2315 case Builtin::BI__sync_fetch_and_nand_2:
2316 case Builtin::BI__sync_fetch_and_nand_4:
2317 case Builtin::BI__sync_fetch_and_nand_8:
2318 case Builtin::BI__sync_fetch_and_nand_16:
2319 case Builtin::BI__sync_add_and_fetch:
2320 case Builtin::BI__sync_add_and_fetch_1:
2321 case Builtin::BI__sync_add_and_fetch_2:
2322 case Builtin::BI__sync_add_and_fetch_4:
2323 case Builtin::BI__sync_add_and_fetch_8:
2324 case Builtin::BI__sync_add_and_fetch_16:
2325 case Builtin::BI__sync_sub_and_fetch:
2326 case Builtin::BI__sync_sub_and_fetch_1:
2327 case Builtin::BI__sync_sub_and_fetch_2:
2328 case Builtin::BI__sync_sub_and_fetch_4:
2329 case Builtin::BI__sync_sub_and_fetch_8:
2330 case Builtin::BI__sync_sub_and_fetch_16:
2331 case Builtin::BI__sync_and_and_fetch:
2332 case Builtin::BI__sync_and_and_fetch_1:
2333 case Builtin::BI__sync_and_and_fetch_2:
2334 case Builtin::BI__sync_and_and_fetch_4:
2335 case Builtin::BI__sync_and_and_fetch_8:
2336 case Builtin::BI__sync_and_and_fetch_16:
2337 case Builtin::BI__sync_or_and_fetch:
2338 case Builtin::BI__sync_or_and_fetch_1:
2339 case Builtin::BI__sync_or_and_fetch_2:
2340 case Builtin::BI__sync_or_and_fetch_4:
2341 case Builtin::BI__sync_or_and_fetch_8:
2342 case Builtin::BI__sync_or_and_fetch_16:
2343 case Builtin::BI__sync_xor_and_fetch:
2344 case Builtin::BI__sync_xor_and_fetch_1:
2345 case Builtin::BI__sync_xor_and_fetch_2:
2346 case Builtin::BI__sync_xor_and_fetch_4:
2347 case Builtin::BI__sync_xor_and_fetch_8:
2348 case Builtin::BI__sync_xor_and_fetch_16:
2349 case Builtin::BI__sync_nand_and_fetch:
2350 case Builtin::BI__sync_nand_and_fetch_1:
2351 case Builtin::BI__sync_nand_and_fetch_2:
2352 case Builtin::BI__sync_nand_and_fetch_4:
2353 case Builtin::BI__sync_nand_and_fetch_8:
2354 case Builtin::BI__sync_nand_and_fetch_16:
2355 case Builtin::BI__sync_val_compare_and_swap:
2356 case Builtin::BI__sync_val_compare_and_swap_1:
2357 case Builtin::BI__sync_val_compare_and_swap_2:
2358 case Builtin::BI__sync_val_compare_and_swap_4:
2359 case Builtin::BI__sync_val_compare_and_swap_8:
2360 case Builtin::BI__sync_val_compare_and_swap_16:
2361 case Builtin::BI__sync_bool_compare_and_swap:
2362 case Builtin::BI__sync_bool_compare_and_swap_1:
2363 case Builtin::BI__sync_bool_compare_and_swap_2:
2364 case Builtin::BI__sync_bool_compare_and_swap_4:
2365 case Builtin::BI__sync_bool_compare_and_swap_8:
2366 case Builtin::BI__sync_bool_compare_and_swap_16:
2367 case Builtin::BI__sync_lock_test_and_set:
2368 case Builtin::BI__sync_lock_test_and_set_1:
2369 case Builtin::BI__sync_lock_test_and_set_2:
2370 case Builtin::BI__sync_lock_test_and_set_4:
2371 case Builtin::BI__sync_lock_test_and_set_8:
2372 case Builtin::BI__sync_lock_test_and_set_16:
2373 case Builtin::BI__sync_lock_release:
2374 case Builtin::BI__sync_lock_release_1:
2375 case Builtin::BI__sync_lock_release_2:
2376 case Builtin::BI__sync_lock_release_4:
2377 case Builtin::BI__sync_lock_release_8:
2378 case Builtin::BI__sync_lock_release_16:
2379 case Builtin::BI__sync_swap:
2380 case Builtin::BI__sync_swap_1:
2381 case Builtin::BI__sync_swap_2:
2382 case Builtin::BI__sync_swap_4:
2383 case Builtin::BI__sync_swap_8:
2384 case Builtin::BI__sync_swap_16:
2385 return BuiltinAtomicOverloaded(TheCallResult);
2386 case Builtin::BI__sync_synchronize:
2390 case Builtin::BI__builtin_nontemporal_load:
2391 case Builtin::BI__builtin_nontemporal_store:
2392 return BuiltinNontemporalOverloaded(TheCallResult);
2393 case Builtin::BI__builtin_memcpy_inline: {
2406 case Builtin::BI__builtin_memset_inline: {
2417 #define BUILTIN(ID, TYPE, ATTRS)
2418 #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2419 case Builtin::BI##ID: \
2420 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2421 #include "clang/Basic/Builtins.inc"
2422 case Builtin::BI__annotation:
2426 case Builtin::BI__builtin_annotation:
2430 case Builtin::BI__builtin_addressof:
2434 case Builtin::BI__builtin_function_start:
2438 case Builtin::BI__builtin_is_aligned:
2439 case Builtin::BI__builtin_align_up:
2440 case Builtin::BI__builtin_align_down:
2444 case Builtin::BI__builtin_add_overflow:
2445 case Builtin::BI__builtin_sub_overflow:
2446 case Builtin::BI__builtin_mul_overflow:
2450 case Builtin::BI__builtin_operator_new:
2451 case Builtin::BI__builtin_operator_delete: {
2452 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2454 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2456 CorrectDelayedTyposInExpr(TheCallResult.get());
2459 case Builtin::BI__builtin_dump_struct:
2461 case Builtin::BI__builtin_expect_with_probability: {
2463 if (checkArgCount(TheCall, 3))
2472 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2475 Diag(PDiag.first, PDiag.second);
2479 bool LoseInfo =
false;
2480 Probability.convert(llvm::APFloat::IEEEdouble(),
2481 llvm::RoundingMode::Dynamic, &LoseInfo);
2490 case Builtin::BI__builtin_preserve_access_index:
2494 case Builtin::BI__builtin_call_with_static_chain:
2498 case Builtin::BI__exception_code:
2499 case Builtin::BI_exception_code:
2501 diag::err_seh___except_block))
2504 case Builtin::BI__exception_info:
2505 case Builtin::BI_exception_info:
2507 diag::err_seh___except_filter))
2510 case Builtin::BI__GetExceptionInfo:
2511 if (checkArgCount(TheCall, 1))
2514 if (CheckCXXThrowOperand(
2522 case Builtin::BIaddressof:
2523 case Builtin::BI__addressof:
2524 case Builtin::BIforward:
2525 case Builtin::BIforward_like:
2526 case Builtin::BImove:
2527 case Builtin::BImove_if_noexcept:
2528 case Builtin::BIas_const: {
2532 if (checkArgCount(TheCall, 1))
2536 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2537 BuiltinID == Builtin::BI__addressof;
2539 (ReturnsPointer ? Result->isAnyPointerType()
2540 : Result->isReferenceType()) &&
2542 Result->getPointeeType()))) {
2543 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2549 case Builtin::BI__builtin_ptrauth_strip:
2551 case Builtin::BI__builtin_ptrauth_blend_discriminator:
2553 case Builtin::BI__builtin_ptrauth_sign_constant:
2556 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
2559 case Builtin::BI__builtin_ptrauth_auth:
2562 case Builtin::BI__builtin_ptrauth_sign_generic_data:
2564 case Builtin::BI__builtin_ptrauth_auth_and_resign:
2566 case Builtin::BI__builtin_ptrauth_string_discriminator:
2569 case Builtin::BIread_pipe:
2570 case Builtin::BIwrite_pipe:
2573 if (
OpenCL().checkBuiltinRWPipe(TheCall))
2576 case Builtin::BIreserve_read_pipe:
2577 case Builtin::BIreserve_write_pipe:
2578 case Builtin::BIwork_group_reserve_read_pipe:
2579 case Builtin::BIwork_group_reserve_write_pipe:
2580 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2583 case Builtin::BIsub_group_reserve_read_pipe:
2584 case Builtin::BIsub_group_reserve_write_pipe:
2585 if (
OpenCL().checkSubgroupExt(TheCall) ||
2586 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2589 case Builtin::BIcommit_read_pipe:
2590 case Builtin::BIcommit_write_pipe:
2591 case Builtin::BIwork_group_commit_read_pipe:
2592 case Builtin::BIwork_group_commit_write_pipe:
2593 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
2596 case Builtin::BIsub_group_commit_read_pipe:
2597 case Builtin::BIsub_group_commit_write_pipe:
2598 if (
OpenCL().checkSubgroupExt(TheCall) ||
2599 OpenCL().checkBuiltinCommitRWPipe(TheCall))
2602 case Builtin::BIget_pipe_num_packets:
2603 case Builtin::BIget_pipe_max_packets:
2604 if (
OpenCL().checkBuiltinPipePackets(TheCall))
2607 case Builtin::BIto_global:
2608 case Builtin::BIto_local:
2609 case Builtin::BIto_private:
2610 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
2614 case Builtin::BIenqueue_kernel:
2615 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
2618 case Builtin::BIget_kernel_work_group_size:
2619 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
2620 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
2623 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2624 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
2625 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
2628 case Builtin::BI__builtin_os_log_format:
2629 Cleanup.setExprNeedsCleanups(
true);
2631 case Builtin::BI__builtin_os_log_format_buffer_size:
2632 if (BuiltinOSLogFormat(TheCall))
2635 case Builtin::BI__builtin_intel_fpga_reg:
2638 <<
"__builtin_intel_fpga_reg"
2642 if (CheckIntelFPGARegBuiltinFunctionCall(BuiltinID, TheCall))
2645 case Builtin::BI__builtin_intel_sycl_ptr_annotation:
2648 <<
"__builtin_intel_sycl_ptr_annotation"
2652 if (CheckIntelSYCLPtrAnnotationBuiltinFunctionCall(BuiltinID, TheCall))
2655 case Builtin::BI__builtin_intel_sycl_alloca:
2656 case Builtin::BI__builtin_intel_sycl_alloca_with_align:
2659 << (BuiltinID == Builtin::BI__builtin_intel_sycl_alloca
2660 ?
"__builtin_intel_sycl_alloca"
2661 :
"__builtin_intel_sycl_alloca_with_align")
2665 if (getASTContext().getTargetInfo().getTriple().isSPIRAOT()) {
2668 << (BuiltinID == Builtin::BI__builtin_intel_sycl_alloca_with_align);
2671 if (CheckIntelSYCLAllocaBuiltinFunctionCall(BuiltinID, TheCall))
2674 case Builtin::BI__builtin_intel_fpga_mem:
2677 <<
"__builtin_intel_fpga_mem"
2681 if (CheckIntelFPGAMemBuiltinFunctionCall(TheCall))
2684 case Builtin::BI__builtin_frame_address:
2685 case Builtin::BI__builtin_return_address: {
2686 if (BuiltinConstantArgRange(TheCall, 0, 0, 0xFFFF))
2694 Result.Val.getInt() != 0)
2696 << ((BuiltinID == Builtin::BI__builtin_return_address)
2697 ?
"__builtin_return_address"
2698 :
"__builtin_frame_address")
2703 case Builtin::BI__builtin_nondeterministic_value: {
2704 if (BuiltinNonDeterministicValue(TheCall))
2711 case Builtin::BI__builtin_elementwise_abs: {
2712 if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2719 EltTy = VecTy->getElementType();
2722 diag::err_builtin_invalid_arg_type)
2731 case Builtin::BI__builtin_elementwise_acos:
2732 case Builtin::BI__builtin_elementwise_asin:
2733 case Builtin::BI__builtin_elementwise_atan:
2734 case Builtin::BI__builtin_elementwise_ceil:
2735 case Builtin::BI__builtin_elementwise_cos:
2736 case Builtin::BI__builtin_elementwise_cosh:
2737 case Builtin::BI__builtin_elementwise_exp:
2738 case Builtin::BI__builtin_elementwise_exp2:
2739 case Builtin::BI__builtin_elementwise_floor:
2740 case Builtin::BI__builtin_elementwise_log:
2741 case Builtin::BI__builtin_elementwise_log2:
2742 case Builtin::BI__builtin_elementwise_log10:
2743 case Builtin::BI__builtin_elementwise_roundeven:
2744 case Builtin::BI__builtin_elementwise_round:
2745 case Builtin::BI__builtin_elementwise_rint:
2746 case Builtin::BI__builtin_elementwise_nearbyint:
2747 case Builtin::BI__builtin_elementwise_sin:
2748 case Builtin::BI__builtin_elementwise_sinh:
2749 case Builtin::BI__builtin_elementwise_sqrt:
2750 case Builtin::BI__builtin_elementwise_tan:
2751 case Builtin::BI__builtin_elementwise_tanh:
2752 case Builtin::BI__builtin_elementwise_trunc:
2753 case Builtin::BI__builtin_elementwise_canonicalize: {
2754 if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2763 case Builtin::BI__builtin_elementwise_fma: {
2764 if (BuiltinElementwiseTernaryMath(TheCall))
2771 case Builtin::BI__builtin_elementwise_pow: {
2772 if (BuiltinElementwiseMath(TheCall))
2786 case Builtin::BI__builtin_elementwise_add_sat:
2787 case Builtin::BI__builtin_elementwise_sub_sat: {
2788 if (BuiltinElementwiseMath(TheCall))
2796 EltTy = VecTy->getElementType();
2806 case Builtin::BI__builtin_elementwise_min:
2807 case Builtin::BI__builtin_elementwise_max:
2808 if (BuiltinElementwiseMath(TheCall))
2812 case Builtin::BI__builtin_elementwise_bitreverse: {
2813 if (PrepareBuiltinElementwiseMathOneArgCall(TheCall))
2821 EltTy = VecTy->getElementType();
2831 case Builtin::BI__builtin_elementwise_copysign: {
2832 if (checkArgCount(TheCall, 2))
2851 diag::err_typecheck_call_different_arg_types)
2852 << MagnitudeTy << SignTy;
2860 case Builtin::BI__builtin_reduce_max:
2861 case Builtin::BI__builtin_reduce_min: {
2862 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2870 ElTy = TyA->getElementType();
2874 if (ElTy.isNull()) {
2886 case Builtin::BI__builtin_reduce_add:
2887 case Builtin::BI__builtin_reduce_mul:
2888 case Builtin::BI__builtin_reduce_xor:
2889 case Builtin::BI__builtin_reduce_or:
2890 case Builtin::BI__builtin_reduce_and: {
2891 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2899 ElTy = TyA->getElementType();
2903 if (ElTy.isNull() || !ElTy->isIntegerType()) {
2913 case Builtin::BI__builtin_matrix_transpose:
2914 return BuiltinMatrixTranspose(TheCall, TheCallResult);
2916 case Builtin::BI__builtin_matrix_column_major_load:
2917 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
2919 case Builtin::BI__builtin_matrix_column_major_store:
2920 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
2922 case Builtin::BI__builtin_verbose_trap:
2927 case Builtin::BI__builtin_get_device_side_mangled_name: {
2928 auto Check = [](
CallExpr *TheCall) {
2934 auto *
D = DRE->getDecl();
2935 if (!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
2940 if (!Check(TheCall)) {
2942 diag::err_hip_invalid_args_builtin_mangled_name);
2947 case Builtin::BI__builtin_popcountg:
2951 case Builtin::BI__builtin_clzg:
2952 case Builtin::BI__builtin_ctzg:
2957 case Builtin::BI__builtin_allow_runtime_check: {
2969 if (getLangOpts().
HLSL &&
HLSL().CheckBuiltinFunctionCall(BuiltinID, TheCall))
2977 "Aux Target Builtin, but not an aux target?");
2979 if (CheckTSBuiltinFunctionCall(
2985 if (getLangOpts().SYCLIsDevice)
2987 diag::err_builtin_target_unsupported);
2989 if (CheckTSBuiltinFunctionCall(Context.
getTargetInfo(), BuiltinID,
2995 return TheCallResult;
3006 if (BuiltinConstantArg(TheCall, ArgNum, Result))
3010 if (Result.isShiftedMask() || (~Result).isShiftedMask())
3014 diag::err_argument_not_contiguous_bit_field)
3025 for (
auto *FD :
Record->fields()) {
3029 T = AT->getElementType();
3049 bool Sema::CheckIntelFPGARegBuiltinFunctionCall(
unsigned BuiltinID,
3051 switch (BuiltinID) {
3052 case Builtin::BI__builtin_intel_fpga_reg: {
3053 if (checkArgCount(TheCall, 1))
3065 Diag(
Loc, diag::illegal_type_declared_here);
3078 bool Sema::CheckIntelFPGAMemBuiltinFunctionCall(
CallExpr *TheCall) {
3079 const unsigned MinNumArgs = 3;
3080 const unsigned MaxNumArgs = 7;
3084 if (checkArgCountAtLeast(TheCall, MinNumArgs))
3088 if (checkArgCountAtMost(TheCall, MaxNumArgs))
3095 if (!isa<PointerType>(PointerArgType))
3097 diag::err_intel_fpga_mem_arg_mismatch)
3106 << (PointeeType->
isRecordType() ? 1 : 0) << PointerArgType
3109 Diag(
Loc, diag::illegal_type_declared_here);
3115 if (BuiltinConstantArg(TheCall, 1, Result))
3119 if (BuiltinConstantArg(TheCall, 2, Result))
3123 diag::err_intel_fpga_mem_arg_mismatch) << 1;
3126 for (
unsigned I = MinNumArgs; I != NumArgs; ++I) {
3127 if (BuiltinConstantArg(TheCall, I, Result))
3133 TheCall->
setType(PointerArgType);
3137 bool Sema::CheckIntelSYCLPtrAnnotationBuiltinFunctionCall(
unsigned BuiltinID,
3141 if (checkArgCountAtLeast(TheCall, 1)) {
3146 if (!(NumArgs & 0x1)) {
3148 diag::err_intel_sycl_ptr_annotation_arg_number_mismatch);
3155 if (!isa<PointerType>(PointerArgType))
3157 diag::err_intel_sycl_ptr_annotation_mismatch)
3162 for (; I <= NumArgs / 2; ++I) {
3166 if (!isa<StringLiteral>(Arg) &&
3169 diag::err_intel_sycl_ptr_annotation_mismatch)
3176 for (; I != NumArgs; ++I) {
3178 if (BuiltinConstantArg(TheCall, I, Result))
3183 TheCall->
setType(PointerArgType);
3189 assert(VD &&
"Expecting valid declaration");
3191 assert(SpecializationId &&
"Expecting a non-null SpecializationId");
3192 assert(SpecializationId->
getKind() == APValue::ValueKind::Struct &&
3193 "Expecting SpecializationId to be of kind Struct");
3195 "Expecting SpecializationId to have a single field for the default "
3198 assert(
Default.isInt() &&
"Expecting the default value to be an integer");
3202 bool Sema::CheckIntelSYCLAllocaBuiltinFunctionCall(
unsigned BuiltinID,
3204 assert(getLangOpts().SYCLIsDevice &&
3205 "Builtin can only be used in SYCL device code");
3207 assert((BuiltinID == Builtin::BI__builtin_intel_sycl_alloca ||
3208 BuiltinID == Builtin::BI__builtin_intel_sycl_alloca_with_align) &&
3209 "Unexpected builtin");
3211 bool IsAlignedAlloca =
3212 BuiltinID == Builtin::BI__builtin_intel_sycl_alloca_with_align;
3214 constexpr
unsigned InvalidIndex = -1;
3215 constexpr
unsigned ElementTypeIndex = 0;
3216 const unsigned AlignmentIndex = IsAlignedAlloca ? 1 : InvalidIndex;
3217 const unsigned SpecNameIndex = IsAlignedAlloca ? 2 : 1;
3224 assert(FD &&
"Builtin cannot be called from a function pointer");
3225 if (!FD->
hasAttr<BuiltinAliasAttr>()) {
3226 Diag(
Loc, diag::err_intel_sycl_alloca_no_alias) << IsAlignedAlloca;
3231 if (checkArgCount(Call, 1))
3235 unsigned DesiredTemplateArgumentsCount = IsAlignedAlloca ? 4 : 3;
3237 if (!CST || CST->
size() != DesiredTemplateArgumentsCount) {
3238 Diag(
Loc, diag::err_intel_sycl_alloca_wrong_template_arg_count)
3239 << IsAlignedAlloca << (CST ? CST->
size() : 0);
3244 constexpr
auto CheckArg = [](
QualType Ty) {
3245 if (!Ty->isLValueReferenceType())
3247 Ty = Ty->getPointeeType();
3248 return !(Ty.getQualifiers().empty() &&
3252 Diag(
Loc, diag::err_intel_sycl_alloca_wrong_arg)
3266 ->getTemplateArgs();
3275 Diag(
Loc, diag::err_intel_sycl_alloca_wrong_type)
3281 const auto CheckSize = [
this, IsAlignedAlloca, SpecNameIndex](
3293 ->getTemplateArgs();
3298 if (DefaultSize < 1)
3299 Diag(
Loc, diag::warn_intel_sycl_alloca_bad_default_value)
3300 << IsAlignedAlloca << DefaultSize.getSExtValue();
3303 if (CheckSize(getASTContext(),
Loc, CST)) {
3306 const SemaDiagnosticBuilder &
D =
3307 Diag(
Loc, diag::err_intel_sycl_alloca_wrong_size);
3308 D << IsAlignedAlloca;
3316 if (IsAlignedAlloca) {
3319 if (!RequestedAlign.isPowerOf2())
3320 return Diag(
Loc, diag::err_alignment_not_power_of_two);
3322 if (RequestedAlign > MaxAllowedAlign)
3323 return Diag(
Loc, diag::err_alignment_too_big) << MaxAllowedAlign;
3325 int64_t AllocaRequiredAlignment =
3327 if (RequestedAlign < AllocaRequiredAlignment)
3328 return Diag(
Loc, diag::err_alignas_underaligned)
3329 << AllocaType << AllocaRequiredAlignment;
3337 if (Format->getFirstArg() == 0)
3339 else if (IsVariadic)
3343 FSI->
FormatIdx = Format->getFormatIdx() - 1;
3345 FSI->
ArgPassingKind == FAPK_VAList ? 0 : Format->getFirstArg() - 1;
3367 if (isa<CXXNullPtrLiteralExpr>(
3382 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3383 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3384 Expr = ILE->getInit(0);
3394 const Expr *ArgExpr,
3398 S.
PDiag(diag::warn_null_arg)
3404 if (
auto nullability =
type->getNullability())
3415 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3421 llvm::SmallBitVector NonNullArgs;
3427 for (
const auto *Arg : Args)
3434 unsigned IdxAST = Idx.getASTIndex();
3435 if (IdxAST >= Args.size())
3437 if (NonNullArgs.empty())
3438 NonNullArgs.resize(Args.size());
3439 NonNullArgs.set(IdxAST);
3444 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3448 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3451 parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3453 unsigned ParamIndex = 0;
3455 I !=
E; ++I, ++ParamIndex) {
3458 if (NonNullArgs.empty())
3459 NonNullArgs.resize(Args.size());
3461 NonNullArgs.set(ParamIndex);
3468 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3473 type = blockType->getPointeeType();
3487 if (NonNullArgs.empty())
3488 NonNullArgs.resize(Args.size());
3490 NonNullArgs.set(Index);
3499 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3500 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3501 if (NonNullArgs[ArgIndex])
3507 StringRef ParamName,
QualType ArgTy,
3535 if (ArgAlign < ParamAlign)
3536 Diag(
Loc, diag::warn_param_mismatched_alignment)
3538 << ParamName << (FDecl !=
nullptr) << FDecl;
3546 if (CurContext->isDependentContext())
3550 llvm::SmallBitVector CheckedVarArgs;
3554 CheckedVarArgs.resize(Args.size());
3556 CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3563 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3564 if (CallType != VariadicDoesNotApply &&
3567 : isa_and_nonnull<FunctionDecl>(FDecl)
3568 ? cast<FunctionDecl>(FDecl)->getNumParams()
3569 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3570 ? cast<ObjCMethodDecl>(FDecl)->param_size()
3573 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3575 if (
const Expr *Arg = Args[ArgIdx]) {
3576 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3577 checkVariadicArgument(Arg, CallType);
3582 if (FDecl || Proto) {
3587 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3588 CheckArgumentWithTypeTag(I, Args,
Loc);
3594 if (!Proto && FDecl) {
3596 if (isa_and_nonnull<FunctionProtoType>(FT))
3602 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3604 bool IsScalableArg =
false;
3605 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3607 if (
const Expr *Arg = Args[ArgIdx]) {
3614 CallType == VariadicDoesNotApply)
3615 PPC().checkAIXMemberAlignment((Arg->
getExprLoc()), Arg);
3619 IsScalableArg =
true;
3621 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3630 if (
auto *CallerFD = dyn_cast<FunctionDecl>(CurContext)) {
3631 llvm::StringMap<bool> CallerFeatureMap;
3633 if (!CallerFeatureMap.contains(
"sme"))
3634 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3636 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3643 const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext);
3645 (IsScalableArg || IsScalableRet)) {
3646 bool IsCalleeStreaming =
3648 bool IsCalleeStreamingCompatible =
3652 if (!IsCalleeStreamingCompatible &&
3656 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3659 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3670 bool CallerHasZAState =
false;
3671 bool CallerHasZT0State =
false;
3673 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3675 CallerHasZAState =
true;
3677 CallerHasZT0State =
true;
3681 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3683 CallerHasZT0State |=
3685 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3691 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3694 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3698 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3699 Diag(
Loc, diag::note_sme_use_preserves_za);
3704 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3705 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3706 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3707 if (!Arg->isValueDependent()) {
3709 if (Arg->EvaluateAsInt(Align, Context)) {
3711 if (!I.isPowerOf2())
3712 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3713 << Arg->getSourceRange();
3716 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3723 diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args,
Loc);
3725 if (FD && FD->
hasAttr<SYCLKernelAttr>())
3726 SYCL().CheckSYCLKernelCall(FD, Args);
3729 if (FD && FD->
isVariadic() && getLangOpts().SYCLIsDevice &&
3730 !isUnevaluatedContext() && !SYCL().isDeclAllowedInSYCLDeviceCode(FD))
3731 SYCL().DiagIfDeviceCode(
Loc, diag::err_sycl_restrict)
3745 VariadicCallType CallType =
3746 Proto->
isVariadic() ? VariadicConstructor : VariadicDoesNotApply;
3748 auto *Ctor = cast<CXXConstructorDecl>(FDecl);
3753 checkCall(FDecl, Proto,
nullptr, Args,
true,
3759 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3760 isa<CXXMethodDecl>(FDecl);
3761 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3762 IsMemberOperatorCall;
3768 Expr *ImplicitThis =
nullptr;
3773 ImplicitThis = Args[0];
3776 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3779 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3791 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3793 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3797 checkCall(FDecl, Proto, ImplicitThis,
llvm::ArrayRef(Args, NumArgs),
3809 CheckTCBEnforcement(TheCall->
getExprLoc(), FDecl);
3811 CheckAbsoluteValueFunction(TheCall, FDecl);
3812 CheckMaxUnsignedZero(TheCall, FDecl);
3813 CheckInfNaNFunction(TheCall, FDecl);
3815 if (getLangOpts().ObjC)
3816 ObjC().DiagnoseCStringFormatDirectiveInCFAPI(FDecl, Args, NumArgs);
3824 case Builtin::BIstrlcpy:
3825 case Builtin::BIstrlcat:
3826 CheckStrlcpycatArguments(TheCall, FnInfo);
3828 case Builtin::BIstrncat:
3829 CheckStrncatArguments(TheCall, FnInfo);
3831 case Builtin::BIfree:
3832 CheckFreeArguments(TheCall);
3835 CheckMemaccessArguments(TheCall, CMId, FnInfo);
3844 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
3845 Ty =
V->getType().getNonReferenceType();
3846 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
3847 Ty = F->getType().getNonReferenceType();
3855 VariadicCallType CallType;
3857 CallType = VariadicDoesNotApply;
3859 CallType = VariadicBlock;
3861 CallType = VariadicFunction;
3864 checkCall(NDecl, Proto,
nullptr,
3873 VariadicCallType CallType = getVariadicCallType(
nullptr, Proto,
3875 checkCall(
nullptr, Proto,
nullptr,
3884 if (!llvm::isValidAtomicOrderingCABI(Ordering))
3887 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3889 case AtomicExpr::AO__c11_atomic_init:
3890 case AtomicExpr::AO__opencl_atomic_init:
3891 llvm_unreachable(
"There is no ordering argument for an init");
3893 case AtomicExpr::AO__c11_atomic_load:
3894 case AtomicExpr::AO__opencl_atomic_load:
3895 case AtomicExpr::AO__hip_atomic_load:
3896 case AtomicExpr::AO__atomic_load_n:
3897 case AtomicExpr::AO__atomic_load:
3898 case AtomicExpr::AO__scoped_atomic_load_n:
3899 case AtomicExpr::AO__scoped_atomic_load:
3900 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
3901 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3903 case AtomicExpr::AO__c11_atomic_store:
3904 case AtomicExpr::AO__opencl_atomic_store:
3905 case AtomicExpr::AO__hip_atomic_store:
3906 case AtomicExpr::AO__atomic_store:
3907 case AtomicExpr::AO__atomic_store_n:
3908 case AtomicExpr::AO__scoped_atomic_store:
3909 case AtomicExpr::AO__scoped_atomic_store_n:
3910 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
3911 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
3912 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3921 CallExpr *TheCall = cast<CallExpr>(TheCallResult.
get());
3965 const unsigned NumForm = GNUCmpXchg + 1;
3966 const unsigned NumArgs[] = { 2, 2, 3, 3, 3, 3, 4, 5, 6 };
3967 const unsigned NumVals[] = { 1, 0, 1, 1, 1, 1, 2, 2, 3 };
3975 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
3976 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
3977 "need to update code for modified forms");
3978 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
3979 AtomicExpr::AO__atomic_xor_fetch + 1 ==
3980 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
3981 "need to update code for modified C11 atomics");
3982 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
3983 Op <= AtomicExpr::AO__opencl_atomic_store;
3984 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
3985 Op <= AtomicExpr::AO__hip_atomic_store;
3986 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
3987 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
3988 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
3989 Op <= AtomicExpr::AO__c11_atomic_store) ||
3991 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
3992 Op == AtomicExpr::AO__atomic_store_n ||
3993 Op == AtomicExpr::AO__atomic_exchange_n ||
3994 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
3995 Op == AtomicExpr::AO__scoped_atomic_load_n ||
3996 Op == AtomicExpr::AO__scoped_atomic_store_n ||
3997 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
3998 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4002 enum ArithOpExtraValueType {
4007 unsigned ArithAllows = AOEVT_None;
4010 case AtomicExpr::AO__c11_atomic_init:
4011 case AtomicExpr::AO__opencl_atomic_init:
4015 case AtomicExpr::AO__c11_atomic_load:
4016 case AtomicExpr::AO__opencl_atomic_load:
4017 case AtomicExpr::AO__hip_atomic_load:
4018 case AtomicExpr::AO__atomic_load_n:
4019 case AtomicExpr::AO__scoped_atomic_load_n:
4023 case AtomicExpr::AO__atomic_load:
4024 case AtomicExpr::AO__scoped_atomic_load:
4028 case AtomicExpr::AO__c11_atomic_store:
4029 case AtomicExpr::AO__opencl_atomic_store:
4030 case AtomicExpr::AO__hip_atomic_store:
4031 case AtomicExpr::AO__atomic_store:
4032 case AtomicExpr::AO__atomic_store_n:
4033 case AtomicExpr::AO__scoped_atomic_store:
4034 case AtomicExpr::AO__scoped_atomic_store_n:
4037 case AtomicExpr::AO__atomic_fetch_add:
4038 case AtomicExpr::AO__atomic_fetch_sub:
4039 case AtomicExpr::AO__atomic_add_fetch:
4040 case AtomicExpr::AO__atomic_sub_fetch:
4041 case AtomicExpr::AO__scoped_atomic_fetch_add:
4042 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4043 case AtomicExpr::AO__scoped_atomic_add_fetch:
4044 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4045 case AtomicExpr::AO__c11_atomic_fetch_add:
4046 case AtomicExpr::AO__c11_atomic_fetch_sub:
4047 case AtomicExpr::AO__opencl_atomic_fetch_add:
4048 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4049 case AtomicExpr::AO__hip_atomic_fetch_add:
4050 case AtomicExpr::AO__hip_atomic_fetch_sub:
4051 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4054 case AtomicExpr::AO__atomic_fetch_max:
4055 case AtomicExpr::AO__atomic_fetch_min:
4056 case AtomicExpr::AO__atomic_max_fetch:
4057 case AtomicExpr::AO__atomic_min_fetch:
4058 case AtomicExpr::AO__scoped_atomic_fetch_max:
4059 case AtomicExpr::AO__scoped_atomic_fetch_min:
4060 case AtomicExpr::AO__scoped_atomic_max_fetch:
4061 case AtomicExpr::AO__scoped_atomic_min_fetch:
4062 case AtomicExpr::AO__c11_atomic_fetch_max:
4063 case AtomicExpr::AO__c11_atomic_fetch_min:
4064 case AtomicExpr::AO__opencl_atomic_fetch_max:
4065 case AtomicExpr::AO__opencl_atomic_fetch_min:
4066 case AtomicExpr::AO__hip_atomic_fetch_max:
4067 case AtomicExpr::AO__hip_atomic_fetch_min:
4068 ArithAllows = AOEVT_FP;
4071 case AtomicExpr::AO__c11_atomic_fetch_and:
4072 case AtomicExpr::AO__c11_atomic_fetch_or:
4073 case AtomicExpr::AO__c11_atomic_fetch_xor:
4074 case AtomicExpr::AO__hip_atomic_fetch_and:
4075 case AtomicExpr::AO__hip_atomic_fetch_or:
4076 case AtomicExpr::AO__hip_atomic_fetch_xor:
4077 case AtomicExpr::AO__c11_atomic_fetch_nand:
4078 case AtomicExpr::AO__opencl_atomic_fetch_and:
4079 case AtomicExpr::AO__opencl_atomic_fetch_or:
4080 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4081 case AtomicExpr::AO__atomic_fetch_and:
4082 case AtomicExpr::AO__atomic_fetch_or:
4083 case AtomicExpr::AO__atomic_fetch_xor:
4084 case AtomicExpr::AO__atomic_fetch_nand:
4085 case AtomicExpr::AO__atomic_and_fetch:
4086 case AtomicExpr::AO__atomic_or_fetch:
4087 case AtomicExpr::AO__atomic_xor_fetch:
4088 case AtomicExpr::AO__atomic_nand_fetch:
4089 case AtomicExpr::AO__scoped_atomic_fetch_and:
4090 case AtomicExpr::AO__scoped_atomic_fetch_or:
4091 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4092 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4093 case AtomicExpr::AO__scoped_atomic_and_fetch:
4094 case AtomicExpr::AO__scoped_atomic_or_fetch:
4095 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4096 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4100 case AtomicExpr::AO__c11_atomic_exchange:
4101 case AtomicExpr::AO__hip_atomic_exchange:
4102 case AtomicExpr::AO__opencl_atomic_exchange:
4103 case AtomicExpr::AO__atomic_exchange_n:
4104 case AtomicExpr::AO__scoped_atomic_exchange_n:
4108 case AtomicExpr::AO__atomic_exchange:
4109 case AtomicExpr::AO__scoped_atomic_exchange:
4113 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4114 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4115 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4116 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4117 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4118 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4122 case AtomicExpr::AO__atomic_compare_exchange:
4123 case AtomicExpr::AO__atomic_compare_exchange_n:
4124 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4125 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4130 unsigned AdjustedNumArgs = NumArgs[Form];
4131 if ((IsOpenCL || IsHIP || IsScoped) &&
4132 Op != AtomicExpr::AO__opencl_atomic_init)
4135 if (Args.size() < AdjustedNumArgs) {
4136 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4137 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4140 }
else if (Args.size() > AdjustedNumArgs) {
4141 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4142 diag::err_typecheck_call_too_many_args)
4143 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4149 Expr *Ptr = Args[0];
4150 ExprResult ConvertedPtr = DefaultFunctionArrayLvalueConversion(Ptr);
4154 Ptr = ConvertedPtr.
get();
4157 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4167 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4173 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4179 }
else if (Form !=
Load && Form != LoadCopy) {
4181 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4188 if (RequireCompleteType(Ptr->
getBeginLoc(), AtomTy,
4189 diag::err_incomplete_type))
4192 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4198 if (Form == Arithmetic) {
4201 auto IsAllowedValueType = [&](
QualType ValType,
4202 unsigned AllowedType) ->
bool {
4206 return AllowedType & AOEVT_Pointer;
4212 &llvm::APFloat::x87DoubleExtended())
4216 if (!IsAllowedValueType(ValType, ArithAllows)) {
4217 auto DID = ArithAllows & AOEVT_FP
4218 ? (ArithAllows & AOEVT_Pointer
4219 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4220 : diag::err_atomic_op_needs_atomic_int_or_fp)
4221 : diag::err_atomic_op_needs_atomic_int;
4228 diag::err_incomplete_type)) {
4234 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4245 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4261 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4273 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg ||
4275 ResultType = Context.
VoidTy;
4276 else if (Form == C11CmpXchg || Form == GNUCmpXchg)
4277 ResultType = Context.
BoolTy;
4282 bool IsPassedByAddress =
false;
4283 if (!IsC11 && !IsHIP && !IsN) {
4285 IsPassedByAddress =
true;
4290 APIOrderedArgs.push_back(Args[0]);
4294 APIOrderedArgs.push_back(Args[1]);
4300 APIOrderedArgs.push_back(Args[2]);
4301 APIOrderedArgs.push_back(Args[1]);
4304 APIOrderedArgs.push_back(Args[2]);
4305 APIOrderedArgs.push_back(Args[3]);
4306 APIOrderedArgs.push_back(Args[1]);
4309 APIOrderedArgs.push_back(Args[2]);
4310 APIOrderedArgs.push_back(Args[4]);
4311 APIOrderedArgs.push_back(Args[1]);
4312 APIOrderedArgs.push_back(Args[3]);
4315 APIOrderedArgs.push_back(Args[2]);
4316 APIOrderedArgs.push_back(Args[4]);
4317 APIOrderedArgs.push_back(Args[5]);
4318 APIOrderedArgs.push_back(Args[1]);
4319 APIOrderedArgs.push_back(Args[3]);
4323 APIOrderedArgs.append(Args.begin(), Args.end());
4330 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4332 if (i < NumVals[Form] + 1) {
4345 assert(Form !=
Load);
4348 else if (Form == Init || Form == Arithmetic)
4350 else if (Form ==
Copy || Form == Xchg) {
4351 if (IsPassedByAddress) {
4358 Expr *ValArg = APIOrderedArgs[i];
4365 AS = PtrTy->getPointeeType().getAddressSpace();
4374 if (IsPassedByAddress)
4394 APIOrderedArgs[i] = Arg.
get();
4399 SubExprs.push_back(Ptr);
4403 SubExprs.push_back(APIOrderedArgs[1]);
4406 SubExprs.push_back(APIOrderedArgs[1]);
4412 SubExprs.push_back(APIOrderedArgs[2]);
4413 SubExprs.push_back(APIOrderedArgs[1]);
4417 SubExprs.push_back(APIOrderedArgs[3]);
4418 SubExprs.push_back(APIOrderedArgs[1]);
4419 SubExprs.push_back(APIOrderedArgs[2]);
4422 SubExprs.push_back(APIOrderedArgs[3]);
4423 SubExprs.push_back(APIOrderedArgs[1]);
4424 SubExprs.push_back(APIOrderedArgs[4]);
4425 SubExprs.push_back(APIOrderedArgs[2]);
4428 SubExprs.push_back(APIOrderedArgs[4]);
4429 SubExprs.push_back(APIOrderedArgs[1]);
4430 SubExprs.push_back(APIOrderedArgs[5]);
4431 SubExprs.push_back(APIOrderedArgs[2]);
4432 SubExprs.push_back(APIOrderedArgs[3]);
4437 if (SubExprs.size() >= 2 && Form != Init) {
4438 std::optional<llvm::APSInt> Success =
4439 SubExprs[1]->getIntegerConstantExpr(Context);
4441 Diag(SubExprs[1]->getBeginLoc(),
4442 diag::warn_atomic_op_has_invalid_memory_order)
4443 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4446 if (SubExprs.size() >= 5) {
4447 if (std::optional<llvm::APSInt> Failure =
4448 SubExprs[3]->getIntegerConstantExpr(Context)) {
4449 if (!llvm::is_contained(
4450 {llvm::AtomicOrderingCABI::relaxed,
4451 llvm::AtomicOrderingCABI::consume,
4452 llvm::AtomicOrderingCABI::acquire,
4453 llvm::AtomicOrderingCABI::seq_cst},
4454 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4455 Diag(SubExprs[3]->getBeginLoc(),
4456 diag::warn_atomic_op_has_invalid_memory_order)
4457 << 2 << SubExprs[3]->getSourceRange();
4464 auto *
Scope = Args[Args.size() - 1];
4465 if (std::optional<llvm::APSInt> Result =
4466 Scope->getIntegerConstantExpr(Context)) {
4467 if (!ScopeModel->isValid(Result->getZExtValue()))
4468 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)
4469 <<
Scope->getSourceRange();
4471 SubExprs.push_back(
Scope);
4477 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4478 Op == AtomicExpr::AO__c11_atomic_store ||
4479 Op == AtomicExpr::AO__opencl_atomic_load ||
4480 Op == AtomicExpr::AO__hip_atomic_load ||
4481 Op == AtomicExpr::AO__opencl_atomic_store ||
4482 Op == AtomicExpr::AO__hip_atomic_store) &&
4485 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4486 Op == AtomicExpr::AO__opencl_atomic_load ||
4487 Op == AtomicExpr::AO__hip_atomic_load)
4492 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4508 assert(Fn &&
"builtin call without direct callee!");
4519 E->setArg(ArgIndex, Arg.
get());
4531 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4533 <<
Callee->getSourceRange();
4543 ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg);
4546 FirstArg = FirstArgResult.
get();
4547 TheCall->
setArg(0, FirstArg);
4559 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4594 #define BUILTIN_ROW(x) \
4595 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4596 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4598 static const unsigned BuiltinIndices[][5] = {
4624 case 1: SizeIndex = 0;
break;
4625 case 2: SizeIndex = 1;
break;
4626 case 4: SizeIndex = 2;
break;
4627 case 8: SizeIndex = 3;
break;
4628 case 16: SizeIndex = 4;
break;
4640 unsigned BuiltinIndex, NumFixed = 1;
4641 bool WarnAboutSemanticsChange =
false;
4642 switch (BuiltinID) {
4643 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4644 case Builtin::BI__sync_fetch_and_add:
4645 case Builtin::BI__sync_fetch_and_add_1:
4646 case Builtin::BI__sync_fetch_and_add_2:
4647 case Builtin::BI__sync_fetch_and_add_4:
4648 case Builtin::BI__sync_fetch_and_add_8:
4649 case Builtin::BI__sync_fetch_and_add_16:
4653 case Builtin::BI__sync_fetch_and_sub:
4654 case Builtin::BI__sync_fetch_and_sub_1:
4655 case Builtin::BI__sync_fetch_and_sub_2:
4656 case Builtin::BI__sync_fetch_and_sub_4:
4657 case Builtin::BI__sync_fetch_and_sub_8:
4658 case Builtin::BI__sync_fetch_and_sub_16:
4662 case Builtin::BI__sync_fetch_and_or:
4663 case Builtin::BI__sync_fetch_and_or_1:
4664 case Builtin::BI__sync_fetch_and_or_2:
4665 case Builtin::BI__sync_fetch_and_or_4:
4666 case Builtin::BI__sync_fetch_and_or_8:
4667 case Builtin::BI__sync_fetch_and_or_16:
4671 case Builtin::BI__sync_fetch_and_and:
4672 case Builtin::BI__sync_fetch_and_and_1:
4673 case Builtin::BI__sync_fetch_and_and_2:
4674 case Builtin::BI__sync_fetch_and_and_4:
4675 case Builtin::BI__sync_fetch_and_and_8:
4676 case Builtin::BI__sync_fetch_and_and_16:
4680 case Builtin::BI__sync_fetch_and_xor:
4681 case Builtin::BI__sync_fetch_and_xor_1:
4682 case Builtin::BI__sync_fetch_and_xor_2:
4683 case Builtin::BI__sync_fetch_and_xor_4:
4684 case Builtin::BI__sync_fetch_and_xor_8:
4685 case Builtin::BI__sync_fetch_and_xor_16:
4689 case Builtin::BI__sync_fetch_and_nand:
4690 case Builtin::BI__sync_fetch_and_nand_1:
4691 case Builtin::BI__sync_fetch_and_nand_2:
4692 case Builtin::BI__sync_fetch_and_nand_4:
4693 case Builtin::BI__sync_fetch_and_nand_8:
4694 case Builtin::BI__sync_fetch_and_nand_16:
4696 WarnAboutSemanticsChange =
true;
4699 case Builtin::BI__sync_add_and_fetch:
4700 case Builtin::BI__sync_add_and_fetch_1:
4701 case Builtin::BI__sync_add_and_fetch_2:
4702 case Builtin::BI__sync_add_and_fetch_4:
4703 case Builtin::BI__sync_add_and_fetch_8:
4704 case Builtin::BI__sync_add_and_fetch_16:
4708 case Builtin::BI__sync_sub_and_fetch:
4709 case Builtin::BI__sync_sub_and_fetch_1:
4710 case Builtin::BI__sync_sub_and_fetch_2:
4711 case Builtin::BI__sync_sub_and_fetch_4:
4712 case Builtin::BI__sync_sub_and_fetch_8:
4713 case Builtin::BI__sync_sub_and_fetch_16:
4717 case Builtin::BI__sync_and_and_fetch:
4718 case Builtin::BI__sync_and_and_fetch_1:
4719 case Builtin::BI__sync_and_and_fetch_2:
4720 case Builtin::BI__sync_and_and_fetch_4:
4721 case Builtin::BI__sync_and_and_fetch_8:
4722 case Builtin::BI__sync_and_and_fetch_16:
4726 case Builtin::BI__sync_or_and_fetch:
4727 case Builtin::BI__sync_or_and_fetch_1:
4728 case Builtin::BI__sync_or_and_fetch_2:
4729 case Builtin::BI__sync_or_and_fetch_4:
4730 case Builtin::BI__sync_or_and_fetch_8:
4731 case Builtin::BI__sync_or_and_fetch_16:
4735 case Builtin::BI__sync_xor_and_fetch:
4736 case Builtin::BI__sync_xor_and_fetch_1:
4737 case Builtin::BI__sync_xor_and_fetch_2:
4738 case Builtin::BI__sync_xor_and_fetch_4:
4739 case Builtin::BI__sync_xor_and_fetch_8:
4740 case Builtin::BI__sync_xor_and_fetch_16:
4744 case Builtin::BI__sync_nand_and_fetch:
4745 case Builtin::BI__sync_nand_and_fetch_1:
4746 case Builtin::BI__sync_nand_and_fetch_2:
4747 case Builtin::BI__sync_nand_and_fetch_4:
4748 case Builtin::BI__sync_nand_and_fetch_8:
4749 case Builtin::BI__sync_nand_and_fetch_16:
4751 WarnAboutSemanticsChange =
true;
4754 case Builtin::BI__sync_val_compare_and_swap:
4755 case Builtin::BI__sync_val_compare_and_swap_1:
4756 case Builtin::BI__sync_val_compare_and_swap_2:
4757 case Builtin::BI__sync_val_compare_and_swap_4:
4758 case Builtin::BI__sync_val_compare_and_swap_8:
4759 case Builtin::BI__sync_val_compare_and_swap_16:
4764 case Builtin::BI__sync_bool_compare_and_swap:
4765 case Builtin::BI__sync_bool_compare_and_swap_1:
4766 case Builtin::BI__sync_bool_compare_and_swap_2:
4767 case Builtin::BI__sync_bool_compare_and_swap_4:
4768 case Builtin::BI__sync_bool_compare_and_swap_8:
4769 case Builtin::BI__sync_bool_compare_and_swap_16:
4772 ResultType = Context.
BoolTy;
4775 case Builtin::BI__sync_lock_test_and_set:
4776 case Builtin::BI__sync_lock_test_and_set_1:
4777 case Builtin::BI__sync_lock_test_and_set_2:
4778 case Builtin::BI__sync_lock_test_and_set_4:
4779 case Builtin::BI__sync_lock_test_and_set_8:
4780 case Builtin::BI__sync_lock_test_and_set_16:
4784 case Builtin::BI__sync_lock_release:
4785 case Builtin::BI__sync_lock_release_1:
4786 case Builtin::BI__sync_lock_release_2:
4787 case Builtin::BI__sync_lock_release_4:
4788 case Builtin::BI__sync_lock_release_8:
4789 case Builtin::BI__sync_lock_release_16:
4792 ResultType = Context.
VoidTy;
4795 case Builtin::BI__sync_swap:
4796 case Builtin::BI__sync_swap_1:
4797 case Builtin::BI__sync_swap_2:
4798 case Builtin::BI__sync_swap_4:
4799 case Builtin::BI__sync_swap_8:
4800 case Builtin::BI__sync_swap_16:
4808 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4809 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
4810 <<
Callee->getSourceRange();
4814 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4815 <<
Callee->getSourceRange();
4817 if (WarnAboutSemanticsChange) {
4818 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4819 <<
Callee->getSourceRange();
4824 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4827 if (NewBuiltinID == BuiltinID)
4828 NewBuiltinDecl = FDecl;
4833 LookupName(Res, TUScope,
true);
4834 assert(Res.getFoundDecl());
4835 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4836 if (!NewBuiltinDecl)
4843 for (
unsigned i = 0; i != NumFixed; ++i) {
4873 ExprResult PromotedCall = ImpCastExprToType(NewDRE, CalleePtrTy,
4874 CK_BuiltinFnToFnPtr);
4886 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
4887 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
4891 return TheCallResult;
4900 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
4901 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
4902 "Unexpected nontemporal load/store builtin!");
4903 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
4904 unsigned numArgs = isStore ? 2 : 1;
4907 if (checkArgCount(TheCall, numArgs))
4914 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
4916 DefaultFunctionArrayLvalueConversion(PointerArg);
4920 PointerArg = PointerArgResult.
get();
4921 TheCall->
setArg(numArgs - 1, PointerArg);
4925 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
4938 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
4945 return TheCallResult;
4950 Context, ValType,
false);
4951 ValArg = PerformCopyInitialization(Entity,
SourceLocation(), ValArg);
4957 return TheCallResult;
4964 auto *
Literal = dyn_cast<StringLiteral>(Arg);
4966 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
4967 Literal = ObjcLiteral->getString();
4981 Result = PerformCopyInitialization(Entity,
SourceLocation(), Result);
4989 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
4990 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
4991 TT.getArch() == llvm::Triple::aarch64_32);
4992 bool IsWindows = TT.isOSWindows();
4993 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
4994 if (IsX64 || IsAArch64) {
5001 return S.
Diag(Fn->getBeginLoc(),
5002 diag::err_ms_va_start_used_in_sysv_function);
5010 return S.
Diag(Fn->getBeginLoc(),
5011 diag::err_va_start_used_in_wrong_abi_function)
5018 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5026 bool IsVariadic =
false;
5029 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5030 IsVariadic =
Block->isVariadic();
5031 Params =
Block->parameters();
5032 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5035 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5036 IsVariadic = MD->isVariadic();
5038 Params = MD->parameters();
5039 }
else if (isa<CapturedDecl>(Caller)) {
5041 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5045 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5050 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5055 *LastParam = Params.empty() ? nullptr : Params.back();
5060 bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5069 if (checkArgCount(TheCall, 2))
5085 bool SecondArgIsLastNamedArgument =
false;
5087 if (std::optional<llvm::APSInt> Val =
5089 Val && LangOpts.C23 && *Val == 0)
5096 bool IsCRegister =
false;
5098 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5099 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5100 SecondArgIsLastNamedArgument = PV == LastParam;
5102 Type = PV->getType();
5103 ParamLoc = PV->getLocation();
5105 PV->getStorageClass() ==
SC_Register && !getLangOpts().CPlusPlus;
5109 if (!SecondArgIsLastNamedArgument)
5111 diag::warn_second_arg_of_va_start_not_last_named_param);
5116 if (!Context.isPromotableIntegerType(Type))
5118 if (!Type->isEnumeralType())
5120 const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
5122 Context.typesAreCompatible(ED->getPromotionType(), Type));
5124 unsigned Reason = 0;
5126 else if (IsCRegister) Reason = 2;
5127 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5128 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5134 bool Sema::BuiltinVAStartARMMicrosoft(
CallExpr *Call) {
5135 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5155 if (
Call->getNumArgs() < 3)
5157 diag::err_typecheck_call_too_few_args_at_least)
5158 << 0 << 3 <<
Call->getNumArgs()
5171 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5174 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5179 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5181 << Arg1->
getType() << ConstCharPtrTy << 1
5184 << 2 << Arg1->
getType() << ConstCharPtrTy;
5189 << Arg2->
getType() << SizeTy << 1
5192 << 3 << Arg2->
getType() << SizeTy;
5197 bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5198 if (checkArgCount(TheCall, 2))
5201 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5211 QualType Res = UsualArithmeticConversions(
5212 OrigArg0, OrigArg1, TheCall->
getExprLoc(), ACK_Comparison);
5229 diag::err_typecheck_call_invalid_ordered_compare)
5237 bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5238 unsigned BuiltinID) {
5239 if (checkArgCount(TheCall, NumArgs))
5243 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5244 BuiltinID == Builtin::BI__builtin_isinf ||
5245 BuiltinID == Builtin::BI__builtin_isinf_sign))
5249 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5250 BuiltinID == Builtin::BI__builtin_isunordered))
5254 bool IsFPClass = NumArgs == 2;
5257 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5261 for (
unsigned i = 0; i < FPArgNo; ++i) {
5267 ExprResult Res = PerformImplicitConversion(Arg, Context.
IntTy, AA_Passing);
5283 OrigArg = UsualUnaryConversions(OrigArg).get();
5285 OrigArg = DefaultFunctionArrayLvalueConversion(OrigArg).get();
5286 TheCall->
setArg(FPArgNo, OrigArg);
5293 VectorResultTy = GetSignedVectorType(ElementTy);
5300 diag::err_typecheck_call_invalid_unary_fp)
5306 if (BuiltinConstantArgRange(TheCall, 1, 0, llvm::fcAllFlags))
5312 if (!VectorResultTy.
isNull())
5313 ResultTy = VectorResultTy;
5315 ResultTy = Context.
IntTy;
5322 bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5323 if (checkArgCount(TheCall, 2))
5327 for (
unsigned I = 0; I != 2; ++I) {
5338 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5342 ExprResult Converted = DefaultLvalueConversion(Arg);
5357 diag::err_typecheck_call_different_arg_types)
5381 diag::err_typecheck_call_too_few_args_at_least)
5389 unsigned numElements = 0;
5404 unsigned numResElements = TheCall->
getNumArgs() - 2;
5413 diag::err_vec_builtin_incompatible_vector)
5420 diag::err_vec_builtin_incompatible_vector)
5425 }
else if (numElements != numResElements) {
5432 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5437 std::optional<llvm::APSInt> Result;
5440 diag::err_shufflevector_nonconstant_argument)
5444 if (Result->isSigned() && Result->isAllOnes())
5447 if (Result->getActiveBits() > 64 ||
5448 Result->getZExtValue() >= numElements * 2)
5450 diag::err_shufflevector_argument_too_large)
5456 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5457 exprs.push_back(TheCall->
getArg(i));
5458 TheCall->
setArg(i,
nullptr);
5476 diag::err_convertvector_non_vector)
5479 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5481 <<
"__builtin_convertvector");
5486 if (SrcElts != DstElts)
5488 diag::err_convertvector_incompatible_vector)
5493 BuiltinLoc, RParenLoc);
5496 bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5499 if (checkArgCountAtMost(TheCall, 3))
5504 for (
unsigned i = 1; i != NumArgs; ++i)
5505 if (BuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
5511 bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5513 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5515 if (checkArgCount(TheCall, 1))
5523 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5526 ExprResult FirstArg = DefaultLvalueConversion(Arg);
5533 bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5540 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5545 bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5551 if (
const auto *UE =
5553 if (UE->getKind() == UETT_AlignOf ||
5554 UE->getKind() == UETT_PreferredAlignOf)
5560 if (!Result.isPowerOf2())
5561 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5576 bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5577 if (checkArgCountRange(TheCall, 2, 3))
5585 DefaultFunctionArrayLvalueConversion(FirstArg);
5589 TheCall->
setArg(0, FirstArgResult.
get());
5598 if (BuiltinConstantArg(TheCall, 1, Result))
5601 if (!Result.isPowerOf2())
5602 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5614 TheCall->
setArg(2, ThirdArg);
5620 bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5621 unsigned BuiltinID =
5622 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5623 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5626 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5627 if (NumArgs < NumRequiredArgs) {
5628 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5629 << 0 << NumRequiredArgs << NumArgs
5632 if (checkArgCountAtMost(TheCall, NumRequiredArgs + 0xff))
5642 if (Arg.isInvalid())
5644 TheCall->
setArg(i, Arg.get());
5649 unsigned FormatIdx = i;
5659 unsigned FirstDataArg = i;
5660 while (i < NumArgs) {
5661 ExprResult Arg = DefaultVariadicArgumentPromotion(
5662 TheCall->
getArg(i), VariadicFunction,
nullptr);
5678 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5680 bool Success = CheckFormatArguments(
5681 Args, FAPK_Variadic, FormatIdx, FirstDataArg, FST_OSLog,
5704 std::optional<llvm::APSInt> R;
5706 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5713 int High,
bool RangeIsError) {
5714 if (isConstantEvaluatedContext())
5724 if (BuiltinConstantArg(TheCall, ArgNum, Result))
5727 if (Result.getSExtValue() < Low || Result.getSExtValue() > High) {
5734 DiagRuntimeBehavior(TheCall->
getBeginLoc(), TheCall,
5735 PDiag(diag::warn_argument_invalid_range)
5736 <<
toString(Result, 10) << Low << High
5753 if (BuiltinConstantArg(TheCall, ArgNum, Result))
5756 if (Result.getSExtValue() % Num != 0)
5772 if (BuiltinConstantArg(TheCall, ArgNum, Result))
5777 if (Result.isStrictlyPositive() && (Result & (Result - 1)) == 0)
5780 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5785 if (
Value.isNegative())
5796 if ((
Value & 0xFF) != 0)
5816 if (BuiltinConstantArg(TheCall, ArgNum, Result))
5820 Result = Result.getLoBits(ArgBits);
5821 Result.setIsUnsigned(
true);
5826 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
5840 if (BuiltinConstantArg(TheCall, ArgNum, Result))
5844 Result = Result.getLoBits(ArgBits);
5845 Result.setIsUnsigned(
true);
5849 (Result > 0 && Result < 0x10000 && (Result & 0xFF) == 0xFF))
5853 diag::err_argument_not_shifted_byte_or_xxff)
5857 bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
5859 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
5866 if (BuiltinConstantArg(TheCall, 1, Result))
5870 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
5876 bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
5878 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
5885 class UncoveredArgHandler {
5886 enum {
Unknown = -1, AllCovered = -2 };
5888 signed FirstUncoveredArg =
Unknown;
5892 UncoveredArgHandler() =
default;
5894 bool hasUncoveredArg()
const {
5895 return (FirstUncoveredArg >= 0);
5898 unsigned getUncoveredArg()
const {
5899 assert(hasUncoveredArg() &&
"no uncovered argument");
5900 return FirstUncoveredArg;
5903 void setAllCovered() {
5906 DiagnosticExprs.clear();
5907 FirstUncoveredArg = AllCovered;
5910 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
5911 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
5914 if (FirstUncoveredArg == AllCovered)
5919 if (NewFirstUncoveredArg == FirstUncoveredArg)
5920 DiagnosticExprs.push_back(StrExpr);
5921 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
5922 DiagnosticExprs.clear();
5923 DiagnosticExprs.push_back(StrExpr);
5924 FirstUncoveredArg = NewFirstUncoveredArg;
5928 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
5931 enum StringLiteralCheckType {
5933 SLCT_UncheckedLiteral,
5941 bool AddendIsRight) {
5942 unsigned BitWidth =
Offset.getBitWidth();
5943 unsigned AddendBitWidth = Addend.getBitWidth();
5945 if (Addend.isUnsigned()) {
5946 Addend = Addend.zext(++AddendBitWidth);
5947 Addend.setIsSigned(
true);
5950 if (AddendBitWidth > BitWidth) {
5952 BitWidth = AddendBitWidth;
5953 }
else if (BitWidth > AddendBitWidth) {
5954 Addend = Addend.sext(BitWidth);
5959 if (BinOpKind == BO_Add)
5960 ResOffset =
Offset.sadd_ov(Addend, Ov);
5962 assert(AddendIsRight && BinOpKind == BO_Sub &&
5963 "operator must be add or sub with addend on the right");
5964 ResOffset =
Offset.ssub_ov(Addend, Ov);
5971 "index (intermediate) result too big");
5985 class FormatStringLiteral {
5993 StringRef getString()
const {
5997 unsigned getByteLength()
const {
6008 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6009 bool isWide()
const {
return FExpr->
isWide(); }
6010 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6011 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6012 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6013 bool isPascal()
const {
return FExpr->
isPascal(); }
6018 unsigned *StartTokenByteOffset =
nullptr)
const {
6020 StartToken, StartTokenByteOffset);
6033 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
6037 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6038 bool IgnoreStringsWithoutSpecifiers);
6044 static StringLiteralCheckType
6049 llvm::SmallBitVector &CheckedVarArgs,
6051 bool IgnoreStringsWithoutSpecifiers =
false) {
6053 return SLCT_NotALiteral;
6055 assert(
Offset.isSigned() &&
"invalid offset");
6058 return SLCT_NotALiteral;
6067 return SLCT_UncheckedLiteral;
6070 case Stmt::InitListExprClass:
6074 Type, CallType,
false,
6075 CheckedVarArgs, UncoveredArg,
Offset,
6076 IgnoreStringsWithoutSpecifiers);
6078 return SLCT_NotALiteral;
6079 case Stmt::BinaryConditionalOperatorClass:
6080 case Stmt::ConditionalOperatorClass: {
6084 cast<AbstractConditionalOperator>(
E);
6089 bool CheckLeft =
true, CheckRight =
true;
6092 if (C->getCond()->EvaluateAsBooleanCondition(
6104 StringLiteralCheckType Left;
6106 Left = SLCT_UncheckedLiteral;
6109 firstDataArg,
Type, CallType, InFunctionCall,
6110 CheckedVarArgs, UncoveredArg,
Offset,
6111 IgnoreStringsWithoutSpecifiers);
6112 if (Left == SLCT_NotALiteral || !CheckRight) {
6118 S, C->getFalseExpr(), Args, APK, format_idx, firstDataArg,
Type,
6119 CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
Offset,
6120 IgnoreStringsWithoutSpecifiers);
6122 return (CheckLeft && Left < Right) ? Left : Right;
6125 case Stmt::ImplicitCastExprClass:
6126 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
6129 case Stmt::OpaqueValueExprClass:
6130 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
6134 return SLCT_NotALiteral;
6136 case Stmt::PredefinedExprClass:
6140 return SLCT_UncheckedLiteral;
6142 case Stmt::DeclRefExprClass: {
6148 bool isConstant =
false;
6152 isConstant = AT->getElementType().isConstant(S.
Context);
6154 isConstant =
T.isConstant(S.
Context) &&
6159 isConstant =
T.isConstant(S.
Context);
6163 if (
const Expr *Init = VD->getAnyInitializer()) {
6165 if (
const InitListExpr *InitList = dyn_cast<InitListExpr>(Init)) {
6166 if (InitList->isStringLiteralInit())
6167 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6170 S, Init, Args, APK, format_idx, firstDataArg,
Type, CallType,
6171 false, CheckedVarArgs, UncoveredArg,
Offset);
6212 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6213 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
6215 bool IsCXXMember =
false;
6216 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D))
6217 IsCXXMember = MD->isInstance();
6219 bool IsVariadic =
false;
6221 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
6222 else if (
const auto *BD = dyn_cast<BlockDecl>(
D))
6223 IsVariadic = BD->isVariadic();
6224 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D))
6225 IsVariadic = OMD->isVariadic();
6232 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx &&
6245 return SLCT_UncheckedLiteral;
6254 return SLCT_NotALiteral;
6257 case Stmt::CallExprClass:
6258 case Stmt::CXXMemberCallExprClass: {
6261 bool IsFirst =
true;
6262 StringLiteralCheckType CommonResult;
6263 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6264 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6266 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6267 InFunctionCall, CheckedVarArgs, UncoveredArg,
Offset,
6268 IgnoreStringsWithoutSpecifiers);
6270 CommonResult = Result;
6275 return CommonResult;
6277 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6279 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6280 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6283 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6284 InFunctionCall, CheckedVarArgs, UncoveredArg,
Offset,
6285 IgnoreStringsWithoutSpecifiers);
6291 Type, CallType,
false,
6292 CheckedVarArgs, UncoveredArg,
Offset,
6293 IgnoreStringsWithoutSpecifiers);
6294 return SLCT_NotALiteral;
6296 case Stmt::ObjCMessageExprClass: {
6297 const auto *ME = cast<ObjCMessageExpr>(
E);
6298 if (
const auto *MD = ME->getMethodDecl()) {
6299 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6308 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6310 MD->getSelector().isKeywordSelector(
6311 {
"localizedStringForKey",
"value",
"table"})) {
6312 IgnoreStringsWithoutSpecifiers =
true;
6315 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6317 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6318 InFunctionCall, CheckedVarArgs, UncoveredArg,
Offset,
6319 IgnoreStringsWithoutSpecifiers);
6323 return SLCT_NotALiteral;
6325 case Stmt::ObjCStringLiteralClass:
6326 case Stmt::StringLiteralClass: {
6332 StrE = cast<StringLiteral>(
E);
6338 return SLCT_NotALiteral;
6340 FormatStringLiteral FStr(StrE,
Offset.sextOrTrunc(64).getSExtValue());
6342 InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,
6343 IgnoreStringsWithoutSpecifiers);
6344 return SLCT_CheckedLiteral;
6347 return SLCT_NotALiteral;
6349 case Stmt::BinaryOperatorClass: {
6363 if (LIsInt != RIsInt) {
6367 if (BinOpKind == BO_Add) {
6380 return SLCT_NotALiteral;
6382 case Stmt::UnaryOperatorClass: {
6384 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6385 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6387 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6397 return SLCT_NotALiteral;
6401 return SLCT_NotALiteral;
6412 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6413 if (isa_and_nonnull<StringLiteral>(LVE))
6420 return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
6421 .Case(
"scanf", FST_Scanf)
6422 .Cases(
"printf",
"printf0",
"syslog", FST_Printf)
6423 .Cases(
"NSString",
"CFString", FST_NSString)
6424 .Case(
"strftime", FST_Strftime)
6425 .Case(
"strfmon", FST_Strfmon)
6426 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err", FST_Kprintf)
6427 .Case(
"freebsd_kprintf", FST_FreeBSDKPrintf)
6428 .Case(
"os_trace", FST_OSLog)
6429 .Case(
"os_log", FST_OSLog)
6430 .Default(FST_Unknown);
6433 bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6437 llvm::SmallBitVector &CheckedVarArgs) {
6438 FormatStringInfo FSI;
6439 if (getFormatStringInfo(Format, IsCXXMember, CallType != VariadicDoesNotApply,
6441 return CheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,
6442 FSI.FirstDataArg, GetFormatStringType(Format),
6443 CallType,
Loc, Range, CheckedVarArgs);
6449 unsigned format_idx,
unsigned firstDataArg,
6450 FormatStringType
Type,
6453 llvm::SmallBitVector &CheckedVarArgs) {
6455 if (format_idx >= Args.size()) {
6460 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6474 UncoveredArgHandler UncoveredArg;
6476 *
this, OrigFormatExpr, Args, APK, format_idx, firstDataArg,
Type,
6478 true, CheckedVarArgs, UncoveredArg,
6482 if (UncoveredArg.hasUncoveredArg()) {
6483 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6484 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6485 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6488 if (CT != SLCT_NotALiteral)
6490 return CT == SLCT_CheckedLiteral;
6494 if (
Type == FST_Strftime)
6502 if (
Type == FST_NSString && SourceMgr.isInSystemMacro(FormatLoc))
6507 if (Args.size() == firstDataArg) {
6508 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6514 case FST_FreeBSDKPrintf:
6517 Diag(FormatLoc, diag::note_format_security_fixit)
6521 Diag(FormatLoc, diag::note_format_security_fixit)
6526 Diag(FormatLoc, diag::warn_format_nonliteral)
6537 const FormatStringLiteral *FExpr;
6538 const Expr *OrigFormatExpr;
6540 const unsigned FirstDataArg;
6541 const unsigned NumDataArgs;
6546 llvm::SmallBitVector CoveredArgs;
6547 bool usesPositionalArgs =
false;
6548 bool atFirstArg =
true;
6549 bool inFunctionCall;
6551 llvm::SmallBitVector &CheckedVarArgs;
6552 UncoveredArgHandler &UncoveredArg;
6555 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6556 const Expr *origFormatExpr,
6558 unsigned numDataArgs,
const char *beg,
6562 llvm::SmallBitVector &CheckedVarArgs,
6563 UncoveredArgHandler &UncoveredArg)
6564 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6565 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6566 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6567 inFunctionCall(inFunctionCall), CallType(callType),
6568 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6569 CoveredArgs.resize(numDataArgs);
6570 CoveredArgs.reset();
6573 void DoneProcessing();
6575 void HandleIncompleteSpecifier(
const char *startSpecifier,
6576 unsigned specifierLen)
override;
6578 void HandleInvalidLengthModifier(
6581 const char *startSpecifier,
unsigned specifierLen,
6584 void HandleNonStandardLengthModifier(
6586 const char *startSpecifier,
unsigned specifierLen);
6588 void HandleNonStandardConversionSpecifier(
6590 const char *startSpecifier,
unsigned specifierLen);
6592 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6594 void HandleInvalidPosition(
const char *startSpecifier,
6595 unsigned specifierLen,
6598 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6600 void HandleNullChar(
const char *nullCharacter)
override;
6602 template <
typename Range>
6604 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6606 bool IsStringLocation, Range StringRange,
6611 const char *startSpec,
6612 unsigned specifierLen,
6613 const char *csStart,
unsigned csLen);
6616 const char *startSpec,
6617 unsigned specifierLen);
6621 unsigned specifierLen);
6624 const Expr *getDataArg(
unsigned i)
const;
6628 const char *startSpecifier,
unsigned specifierLen,
6631 template <
typename Range>
6633 bool IsStringLocation, Range StringRange,
6639 SourceRange CheckFormatHandler::getFormatStringRange() {
6644 getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
6654 SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
6659 void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
6660 unsigned specifierLen){
6661 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
6662 getLocationOfByte(startSpecifier),
6664 getSpecifierRange(startSpecifier, specifierLen));
6667 void CheckFormatHandler::HandleInvalidLengthModifier(
6670 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
6671 using namespace analyze_format_string;
6673 const LengthModifier &LM = FS.getLengthModifier();
6674 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6677 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6679 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6680 getLocationOfByte(LM.getStart()),
6682 getSpecifierRange(startSpecifier, specifierLen));
6684 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6685 << FixedLM->toString()
6690 if (DiagID == diag::warn_format_nonsensical_length)
6693 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6694 getLocationOfByte(LM.getStart()),
6696 getSpecifierRange(startSpecifier, specifierLen),
6701 void CheckFormatHandler::HandleNonStandardLengthModifier(
6703 const char *startSpecifier,
unsigned specifierLen) {
6704 using namespace analyze_format_string;
6706 const LengthModifier &LM = FS.getLengthModifier();
6707 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6710 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6712 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6713 << LM.toString() << 0,
6714 getLocationOfByte(LM.getStart()),
6716 getSpecifierRange(startSpecifier, specifierLen));
6718 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6719 << FixedLM->toString()
6723 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6724 << LM.toString() << 0,
6725 getLocationOfByte(LM.getStart()),
6727 getSpecifierRange(startSpecifier, specifierLen));
6731 void CheckFormatHandler::HandleNonStandardConversionSpecifier(
6733 const char *startSpecifier,
unsigned specifierLen) {
6734 using namespace analyze_format_string;
6739 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6743 getSpecifierRange(startSpecifier, specifierLen));
6746 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
6747 << FixedCS->toString()
6750 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6754 getSpecifierRange(startSpecifier, specifierLen));
6758 void CheckFormatHandler::HandlePosition(
const char *startPos,
6760 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
6761 getLocationOfByte(startPos),
6763 getSpecifierRange(startPos, posLen));
6766 void CheckFormatHandler::HandleInvalidPosition(
6767 const char *startSpecifier,
unsigned specifierLen,
6769 EmitFormatDiagnostic(
6770 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
6771 getLocationOfByte(startSpecifier),
true,
6772 getSpecifierRange(startSpecifier, specifierLen));
6775 void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
6777 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
6778 getLocationOfByte(startPos),
6780 getSpecifierRange(startPos, posLen));
6783 void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
6784 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
6786 EmitFormatDiagnostic(
6787 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
6788 getLocationOfByte(nullCharacter),
true,
6789 getFormatStringRange());
6795 const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
6796 return Args[FirstDataArg + i];
6799 void CheckFormatHandler::DoneProcessing() {
6805 signed notCoveredArg = CoveredArgs.find_first();
6806 if (notCoveredArg >= 0) {
6807 assert((
unsigned)notCoveredArg < NumDataArgs);
6808 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
6810 UncoveredArg.setAllCovered();
6815 void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
6816 const Expr *ArgExpr) {
6817 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
6829 for (
auto E : DiagnosticExprs)
6832 CheckFormatHandler::EmitFormatDiagnostic(
6833 S, IsFunctionCall, DiagnosticExprs[0],
6839 CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
6841 const char *startSpec,
6842 unsigned specifierLen,
6843 const char *csStart,
6845 bool keepGoing =
true;
6846 if (argIndex < NumDataArgs) {
6849 CoveredArgs.set(argIndex);
6865 std::string CodePointStr;
6866 if (!llvm::sys::locale::isPrint(*csStart)) {
6867 llvm::UTF32 CodePoint;
6868 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
6869 const llvm::UTF8 *
E =
6870 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
6871 llvm::ConversionResult Result =
6872 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
6874 if (Result != llvm::conversionOK) {
6875 unsigned char FirstChar = *csStart;
6876 CodePoint = (llvm::UTF32)FirstChar;
6879 llvm::raw_string_ostream OS(CodePointStr);
6880 if (CodePoint < 256)
6881 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
6882 else if (CodePoint <= 0xFFFF)
6883 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
6885 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
6890 EmitFormatDiagnostic(
6892 true, getSpecifierRange(startSpec, specifierLen));
6899 const char *startSpec,
6900 unsigned specifierLen) {
6901 EmitFormatDiagnostic(
6902 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
6903 Loc,
true, getSpecifierRange(startSpec, specifierLen));
6907 CheckFormatHandler::CheckNumArgs(
6910 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
6912 if (argIndex >= NumDataArgs) {
6914 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
6915 << (argIndex+1) << NumDataArgs)
6916 : S.
PDiag(diag::warn_printf_insufficient_data_args);
6917 EmitFormatDiagnostic(
6918 PDiag, getLocationOfByte(CS.
getStart()),
true,
6919 getSpecifierRange(startSpecifier, specifierLen));
6923 UncoveredArg.setAllCovered();
6929 template<
typename Range>
6932 bool IsStringLocation,
6935 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
6936 Loc, IsStringLocation, StringRange,
FixIt);
6966 template <
typename Range>
6967 void CheckFormatHandler::EmitFormatDiagnostic(
6968 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
6971 if (InFunctionCall) {
6972 const Sema::SemaDiagnosticBuilder &
D = S.
Diag(
Loc, PDiag);
6979 const Sema::SemaDiagnosticBuilder &
Note =
6980 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
6981 diag::note_format_string_defined);
6983 Note << StringRange;
6992 class CheckPrintfHandler :
public CheckFormatHandler {
6994 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6995 const Expr *origFormatExpr,
6997 unsigned numDataArgs,
bool isObjC,
const char *beg,
7001 llvm::SmallBitVector &CheckedVarArgs,
7002 UncoveredArgHandler &UncoveredArg)
7003 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7004 numDataArgs, beg, APK, Args, formatIdx,
7005 inFunctionCall, CallType, CheckedVarArgs,
7011 bool allowsObjCArg()
const {
7016 bool HandleInvalidPrintfConversionSpecifier(
7018 const char *startSpecifier,
7019 unsigned specifierLen)
override;
7021 void handleInvalidMaskType(StringRef MaskType)
override;
7024 const char *startSpecifier,
unsigned specifierLen,
7027 const char *StartSpecifier,
7028 unsigned SpecifierLen,
7032 const char *startSpecifier,
unsigned specifierLen);
7034 const analyze_printf::OptionalAmount &Amt,
7036 const char *startSpecifier,
unsigned specifierLen);
7038 const analyze_printf::OptionalFlag &flag,
7039 const char *startSpecifier,
unsigned specifierLen);
7041 const analyze_printf::OptionalFlag &ignoredFlag,
7042 const analyze_printf::OptionalFlag &flag,
7043 const char *startSpecifier,
unsigned specifierLen);
7044 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7047 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7048 unsigned flagLen)
override;
7050 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7051 unsigned flagLen)
override;
7053 void HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7054 const char *flagsEnd,
7055 const char *conversionPosition)
7061 bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7063 const char *startSpecifier,
7064 unsigned specifierLen) {
7066 FS.getConversionSpecifier();
7068 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7070 startSpecifier, specifierLen,
7074 void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7075 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7078 bool CheckPrintfHandler::HandleAmount(
7080 const char *startSpecifier,
unsigned specifierLen) {
7084 if (argIndex >= NumDataArgs) {
7085 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
7089 getSpecifierRange(startSpecifier, specifierLen));
7099 CoveredArgs.set(argIndex);
7100 const Expr *Arg = getDataArg(argIndex);
7107 assert(AT.isValid());
7109 if (!AT.matchesType(S.
Context,
T)) {
7110 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
7111 << k << AT.getRepresentativeTypeName(S.
Context)
7115 getSpecifierRange(startSpecifier, specifierLen));
7125 void CheckPrintfHandler::HandleInvalidAmount(
7127 const analyze_printf::OptionalAmount &Amt,
7129 const char *startSpecifier,
7130 unsigned specifierLen) {
7132 FS.getConversionSpecifier();
7137 Amt.getConstantLength()))
7140 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7142 getLocationOfByte(Amt.getStart()),
7144 getSpecifierRange(startSpecifier, specifierLen),
7149 const analyze_printf::OptionalFlag &flag,
7150 const char *startSpecifier,
7151 unsigned specifierLen) {
7154 FS.getConversionSpecifier();
7155 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7156 << flag.toString() << CS.
toString(),
7157 getLocationOfByte(flag.getPosition()),
7159 getSpecifierRange(startSpecifier, specifierLen),
7161 getSpecifierRange(flag.getPosition(), 1)));
7164 void CheckPrintfHandler::HandleIgnoredFlag(
7166 const analyze_printf::OptionalFlag &ignoredFlag,
7167 const analyze_printf::OptionalFlag &flag,
7168 const char *startSpecifier,
7169 unsigned specifierLen) {
7171 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7172 << ignoredFlag.toString() << flag.toString(),
7173 getLocationOfByte(ignoredFlag.getPosition()),
7175 getSpecifierRange(startSpecifier, specifierLen),
7177 getSpecifierRange(ignoredFlag.getPosition(), 1)));
7180 void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7183 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7184 getLocationOfByte(startFlag),
7186 getSpecifierRange(startFlag, flagLen));
7189 void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7192 auto Range = getSpecifierRange(startFlag, flagLen);
7193 StringRef flag(startFlag, flagLen);
7194 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7195 getLocationOfByte(startFlag),
7200 void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7201 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7203 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7204 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7205 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
7206 getLocationOfByte(conversionPosition),
7214 template<
typename MemberKind>
7235 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
7249 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
7250 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7252 if ((*MI)->getMinRequiredArguments() == 0)
7260 bool CheckPrintfHandler::checkForCStrMembers(
7265 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
7267 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7283 bool CheckPrintfHandler::HandlePrintfSpecifier(
7286 using namespace analyze_format_string;
7287 using namespace analyze_printf;
7289 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
7291 if (FS.consumesDataArgument()) {
7294 usesPositionalArgs = FS.usesPositionalArg();
7296 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7297 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7298 startSpecifier, specifierLen);
7305 if (!HandleAmount(FS.getFieldWidth(), 0,
7306 startSpecifier, specifierLen)) {
7310 if (!HandleAmount(FS.getPrecision(), 1,
7311 startSpecifier, specifierLen)) {
7315 if (!CS.consumesDataArgument()) {
7322 unsigned argIndex = FS.getArgIndex();
7323 if (argIndex < NumDataArgs) {
7327 CoveredArgs.set(argIndex);
7331 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
7332 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
7334 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
7338 CoveredArgs.set(argIndex + 1);
7341 const Expr *Ex = getDataArg(argIndex);
7342 const analyze_printf::ArgType &AT =
7343 (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
7346 EmitFormatDiagnostic(
7347 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7351 getSpecifierRange(startSpecifier, specifierLen));
7354 Ex = getDataArg(argIndex + 1);
7355 const analyze_printf::ArgType &AT2 = ArgType::CStrTy;
7357 EmitFormatDiagnostic(
7358 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7362 getSpecifierRange(startSpecifier, specifierLen));
7369 if (!allowsObjCArg() && CS.isObjCArg()) {
7370 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7375 if (FSType !=
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) {
7376 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7381 if (FSType ==
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) {
7382 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
7383 getLocationOfByte(CS.getStart()),
7385 getSpecifierRange(startSpecifier, specifierLen));
7392 (CS.getKind() == ConversionSpecifier::PArg ||
7393 CS.getKind() == ConversionSpecifier::sArg ||
7394 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
7395 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7401 if (FS.isPublic().isSet()) {
7402 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7404 getLocationOfByte(FS.isPublic().getPosition()),
7406 getSpecifierRange(startSpecifier, specifierLen));
7408 if (FS.isPrivate().isSet()) {
7409 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7411 getLocationOfByte(FS.isPrivate().getPosition()),
7413 getSpecifierRange(startSpecifier, specifierLen));
7417 const llvm::Triple &Triple =
Target.getTriple();
7418 if (CS.getKind() == ConversionSpecifier::nArg &&
7419 (Triple.isAndroid() || Triple.isOSFuchsia())) {
7420 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
7421 getLocationOfByte(CS.getStart()),
7423 getSpecifierRange(startSpecifier, specifierLen));
7427 if (!FS.hasValidFieldWidth()) {
7428 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
7429 startSpecifier, specifierLen);
7433 if (!FS.hasValidPrecision()) {
7434 HandleInvalidAmount(FS, FS.getPrecision(), 1,
7435 startSpecifier, specifierLen);
7439 if (CS.getKind() == ConversionSpecifier::PArg &&
7440 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
7441 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
7442 getLocationOfByte(startSpecifier),
7444 getSpecifierRange(startSpecifier, specifierLen));
7448 if (!FS.hasValidThousandsGroupingPrefix())
7449 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
7450 if (!FS.hasValidLeadingZeros())
7451 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
7452 if (!FS.hasValidPlusPrefix())
7453 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
7454 if (!FS.hasValidSpacePrefix())
7455 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
7456 if (!FS.hasValidAlternativeForm())
7457 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
7458 if (!FS.hasValidLeftJustified())
7459 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
7462 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
7463 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
7464 startSpecifier, specifierLen);
7465 if (FS.hasLeadingZeros() && FS.isLeftJustified())
7466 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
7467 startSpecifier, specifierLen);
7472 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7473 diag::warn_format_nonsensical_length);
7474 else if (!FS.hasStandardLengthModifier())
7475 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7476 else if (!FS.hasStandardLengthConversionCombination())
7477 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7478 diag::warn_format_non_standard_conversion_spec);
7480 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7481 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7487 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7490 const Expr *Arg = getDataArg(argIndex);
7494 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
7506 case Stmt::ArraySubscriptExprClass:
7507 case Stmt::CallExprClass:
7508 case Stmt::CharacterLiteralClass:
7509 case Stmt::CXXBoolLiteralExprClass:
7510 case Stmt::DeclRefExprClass:
7511 case Stmt::FloatingLiteralClass:
7512 case Stmt::IntegerLiteralClass:
7513 case Stmt::MemberExprClass:
7514 case Stmt::ObjCArrayLiteralClass:
7515 case Stmt::ObjCBoolLiteralExprClass:
7516 case Stmt::ObjCBoxedExprClass:
7517 case Stmt::ObjCDictionaryLiteralClass:
7518 case Stmt::ObjCEncodeExprClass:
7519 case Stmt::ObjCIvarRefExprClass:
7520 case Stmt::ObjCMessageExprClass:
7521 case Stmt::ObjCPropertyRefExprClass:
7522 case Stmt::ObjCStringLiteralClass:
7523 case Stmt::ObjCSubscriptRefExprClass:
7524 case Stmt::ParenExprClass:
7525 case Stmt::StringLiteralClass:
7526 case Stmt::UnaryOperatorClass:
7533 static std::pair<QualType, StringRef>
7540 StringRef Name = UserTy->getDecl()->getName();
7541 QualType CastTy = llvm::StringSwitch<QualType>(Name)
7545 .Case(
"SInt32", Context.
IntTy)
7550 return std::make_pair(CastTy, Name);
7552 TyTy = UserTy->desugar();
7556 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
7558 PE->getSubExpr()->getType(),
7567 StringRef TrueName, FalseName;
7569 std::tie(TrueTy, TrueName) =
7571 CO->getTrueExpr()->getType(),
7573 std::tie(FalseTy, FalseName) =
7575 CO->getFalseExpr()->getType(),
7576 CO->getFalseExpr());
7578 if (TrueTy == FalseTy)
7579 return std::make_pair(TrueTy, TrueName);
7580 else if (TrueTy.
isNull())
7581 return std::make_pair(FalseTy, FalseName);
7582 else if (FalseTy.
isNull())
7583 return std::make_pair(TrueTy, TrueName);
7586 return std::make_pair(
QualType(), StringRef());
7605 From = VecTy->getElementType();
7607 To = VecTy->getElementType();
7619 diag::warn_format_conversion_argument_type_mismatch_signedness,
Loc)
7628 const char *StartSpecifier,
7629 unsigned SpecifierLen,
7631 using namespace analyze_format_string;
7632 using namespace analyze_printf;
7636 const analyze_printf::ArgType &AT = FS.getArgType(S.
Context, isObjCContext());
7641 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
7642 ExprTy = TET->getUnderlyingExpr()->getType();
7654 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
7657 getSpecifierRange(StartSpecifier, SpecifierLen);
7659 llvm::raw_svector_ostream os(FSString);
7661 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
7669 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
7672 getSpecifierRange(StartSpecifier, SpecifierLen);
7673 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
7678 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
7679 ArgType::MatchKind Match = AT.matchesType(S.
Context, ExprTy);
7680 ArgType::MatchKind OrigMatch = Match;
7683 if (Match == ArgType::Match)
7687 assert(Match != ArgType::NoMatchPromotionTypeConfusion);
7696 E = ICE->getSubExpr();
7705 ImplicitMatch = AT.matchesType(S.
Context, ExprTy);
7706 if (OrigMatch == ArgType::NoMatchSignedness &&
7707 ImplicitMatch != ArgType::NoMatchSignedness)
7714 if (ImplicitMatch == ArgType::Match)
7725 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
7732 if (Match == ArgType::MatchPromotion)
7733 Match = ArgType::NoMatch;
7736 if (Match == ArgType::MatchPromotion) {
7740 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
7741 ImplicitMatch != ArgType::NoMatchTypeConfusion)
7743 Match = ArgType::NoMatch;
7745 if (ImplicitMatch == ArgType::NoMatchPedantic ||
7746 ImplicitMatch == ArgType::NoMatchTypeConfusion)
7747 Match = ImplicitMatch;
7748 assert(Match != ArgType::MatchPromotion);
7751 bool IsEnum =
false;
7752 bool IsScopedEnum =
false;
7755 IntendedTy = EnumTy->getDecl()->getIntegerType();
7756 if (EnumTy->isUnscopedEnumerationType()) {
7757 ExprTy = IntendedTy;
7762 IsScopedEnum =
true;
7769 if (isObjCContext() &&
7770 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
7790 if (TD->getUnderlyingType() == IntendedTy)
7798 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
7806 if (!IsScopedEnum &&
7807 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
7808 (AT.isSizeT() || AT.isPtrdiffT()) &&
7809 AT.matchesType(S.
Context, CastTy))
7810 Match = ArgType::NoMatchPedantic;
7811 IntendedTy = CastTy;
7812 ShouldNotPrintDirectly =
true;
7817 PrintfSpecifier fixedFS = FS;
7824 llvm::raw_svector_ostream os(buf);
7825 fixedFS.toString(os);
7827 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
7829 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
7832 case ArgType::Match:
7833 case ArgType::MatchPromotion:
7834 case ArgType::NoMatchPromotionTypeConfusion:
7835 case ArgType::NoMatchSignedness:
7836 llvm_unreachable(
"expected non-matching");
7837 case ArgType::NoMatchPedantic:
7838 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7840 case ArgType::NoMatchTypeConfusion:
7841 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7843 case ArgType::NoMatch:
7844 Diag = diag::warn_format_conversion_argument_type_mismatch;
7851 << AT.getRepresentativeTypeName(S.
Context)
7865 llvm::raw_svector_ostream CastFix(CastBuf);
7866 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
7868 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
7871 ArgType::MatchKind IntendedMatch = AT.matchesType(S.
Context, IntendedTy);
7874 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
7879 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
7901 if (ShouldNotPrintDirectly && !IsScopedEnum) {
7907 Name = TypedefTy->getDecl()->getName();
7910 unsigned Diag = Match == ArgType::NoMatchPedantic
7911 ? diag::warn_format_argument_needs_cast_pedantic
7912 : diag::warn_format_argument_needs_cast;
7913 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
7924 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7925 : diag::warn_format_conversion_argument_type_mismatch;
7927 EmitFormatDiagnostic(
7939 bool EmitTypeMismatch =
false;
7945 case ArgType::Match:
7946 case ArgType::MatchPromotion:
7947 case ArgType::NoMatchPromotionTypeConfusion:
7948 case ArgType::NoMatchSignedness:
7949 llvm_unreachable(
"expected non-matching");
7950 case ArgType::NoMatchPedantic:
7951 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7953 case ArgType::NoMatchTypeConfusion:
7954 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7956 case ArgType::NoMatch:
7957 Diag = diag::warn_format_conversion_argument_type_mismatch;
7961 EmitFormatDiagnostic(
7970 EmitTypeMismatch =
true;
7972 EmitFormatDiagnostic(
7973 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
7974 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7975 << AT.getRepresentativeTypeName(S.
Context) << CSR
7978 checkForCStrMembers(AT,
E);
7984 EmitTypeMismatch =
true;
7986 EmitFormatDiagnostic(
7987 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
7988 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7989 << AT.getRepresentativeTypeName(S.
Context) << CSR
7996 << isa<InitListExpr>(
E) << ExprTy << CallType
8001 if (EmitTypeMismatch) {
8007 EmitFormatDiagnostic(
8008 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8009 << AT.getRepresentativeTypeName(S.
Context) << ExprTy <<
false
8014 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
8015 "format string specifier index out of range");
8016 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
8026 class CheckScanfHandler :
public CheckFormatHandler {
8028 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
8030 unsigned firstDataArg,
unsigned numDataArgs,
8034 llvm::SmallBitVector &CheckedVarArgs,
8035 UncoveredArgHandler &UncoveredArg)
8036 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8037 numDataArgs, beg, APK, Args, formatIdx,
8038 inFunctionCall, CallType, CheckedVarArgs,
8042 const char *startSpecifier,
8043 unsigned specifierLen)
override;
8045 bool HandleInvalidScanfConversionSpecifier(
8047 const char *startSpecifier,
8048 unsigned specifierLen)
override;
8050 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
8055 void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
8057 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
8058 getLocationOfByte(end),
true,
8059 getSpecifierRange(start, end - start));
8062 bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
8064 const char *startSpecifier,
8065 unsigned specifierLen) {
8067 FS.getConversionSpecifier();
8069 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
8071 startSpecifier, specifierLen,
8075 bool CheckScanfHandler::HandleScanfSpecifier(
8077 const char *startSpecifier,
8078 unsigned specifierLen) {
8079 using namespace analyze_scanf;
8080 using namespace analyze_format_string;
8082 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
8086 if (FS.consumesDataArgument()) {
8089 usesPositionalArgs = FS.usesPositionalArg();
8091 else if (usesPositionalArgs != FS.usesPositionalArg()) {
8092 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8093 startSpecifier, specifierLen);
8099 const OptionalAmount &Amt = FS.getFieldWidth();
8100 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
8101 if (Amt.getConstantAmount() == 0) {
8103 Amt.getConstantLength());
8104 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
8105 getLocationOfByte(Amt.getStart()),
8111 if (!FS.consumesDataArgument()) {
8118 unsigned argIndex = FS.getArgIndex();
8119 if (argIndex < NumDataArgs) {
8123 CoveredArgs.set(argIndex);
8129 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8130 diag::warn_format_nonsensical_length);
8131 else if (!FS.hasStandardLengthModifier())
8132 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8133 else if (!FS.hasStandardLengthConversionCombination())
8134 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8135 diag::warn_format_non_standard_conversion_spec);
8137 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
8138 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8144 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8148 const Expr *Ex = getDataArg(argIndex);
8165 ScanfSpecifier fixedFS = FS;
8170 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8171 : diag::warn_format_conversion_argument_type_mismatch;
8176 llvm::raw_svector_ostream os(buf);
8177 fixedFS.toString(os);
8179 EmitFormatDiagnostic(
8184 getSpecifierRange(startSpecifier, specifierLen),
8186 getSpecifierRange(startSpecifier, specifierLen), os.str()));
8193 getSpecifierRange(startSpecifier, specifierLen));
8200 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
8204 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
8205 bool IgnoreStringsWithoutSpecifiers) {
8207 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
8208 CheckFormatHandler::EmitFormatDiagnostic(
8209 S, inFunctionCall, Args[format_idx],
8210 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
8216 StringRef StrRef = FExpr->getString();
8217 const char *Str = StrRef.data();
8221 assert(
T &&
"String literal not of constant array type!");
8222 size_t TypeSize =
T->getZExtSize();
8223 size_t StrLen =
std::min(
std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8224 const unsigned numDataArgs = Args.size() - firstDataArg;
8226 if (IgnoreStringsWithoutSpecifiers &&
8233 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
8234 CheckFormatHandler::EmitFormatDiagnostic(
8235 S, inFunctionCall, Args[format_idx],
8236 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
8237 FExpr->getBeginLoc(),
8243 if (StrLen == 0 && numDataArgs > 0) {
8244 CheckFormatHandler::EmitFormatDiagnostic(
8245 S, inFunctionCall, Args[format_idx],
8246 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
8254 CheckPrintfHandler H(
8255 S, FExpr, OrigFormatExpr,
Type, firstDataArg, numDataArgs,
8257 Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,
8265 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
8266 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
8267 CallType, CheckedVarArgs, UncoveredArg);
8278 const char *Str = StrRef.data();
8281 assert(
T &&
"String literal not of constant array type!");
8282 size_t TypeSize =
T->getZExtSize();
8283 size_t StrLen =
std::min(
std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8294 switch (AbsFunction) {
8298 case Builtin::BI__builtin_abs:
8299 return Builtin::BI__builtin_labs;
8300 case Builtin::BI__builtin_labs:
8301 return Builtin::BI__builtin_llabs;
8302 case Builtin::BI__builtin_llabs:
8305 case Builtin::BI__builtin_fabsf:
8306 return Builtin::BI__builtin_fabs;
8307 case Builtin::BI__builtin_fabs:
8308 return Builtin::BI__builtin_fabsl;
8309 case Builtin::BI__builtin_fabsl:
8312 case Builtin::BI__builtin_cabsf:
8313 return Builtin::BI__builtin_cabs;
8314 case Builtin::BI__builtin_cabs:
8315 return Builtin::BI__builtin_cabsl;
8316 case Builtin::BI__builtin_cabsl:
8319 case Builtin::BIabs:
8320 return Builtin::BIlabs;
8321 case Builtin::BIlabs:
8322 return Builtin::BIllabs;
8323 case Builtin::BIllabs:
8326 case Builtin::BIfabsf:
8327 return Builtin::BIfabs;
8328 case Builtin::BIfabs:
8329 return Builtin::BIfabsl;
8330 case Builtin::BIfabsl:
8333 case Builtin::BIcabsf:
8334 return Builtin::BIcabs;
8335 case Builtin::BIcabs:
8336 return Builtin::BIcabsl;
8337 case Builtin::BIcabsl:
8366 unsigned AbsFunctionKind) {
8367 unsigned BestKind = 0;
8369 for (
unsigned Kind = AbsFunctionKind;
Kind != 0;
8375 else if (Context.
hasSameType(ParamType, ArgType)) {
8398 llvm_unreachable(
"Type not integer, floating, or complex");
8405 switch (ValueKind) {
8410 case Builtin::BI__builtin_fabsf:
8411 case Builtin::BI__builtin_fabs:
8412 case Builtin::BI__builtin_fabsl:
8413 case Builtin::BI__builtin_cabsf:
8414 case Builtin::BI__builtin_cabs:
8415 case Builtin::BI__builtin_cabsl:
8416 return Builtin::BI__builtin_abs;
8417 case Builtin::BIfabsf:
8418 case Builtin::BIfabs:
8419 case Builtin::BIfabsl:
8420 case Builtin::BIcabsf:
8421 case Builtin::BIcabs:
8422 case Builtin::BIcabsl:
8423 return Builtin::BIabs;
8429 case Builtin::BI__builtin_abs:
8430 case Builtin::BI__builtin_labs:
8431 case Builtin::BI__builtin_llabs:
8432 case Builtin::BI__builtin_cabsf:
8433 case Builtin::BI__builtin_cabs:
8434 case Builtin::BI__builtin_cabsl:
8435 return Builtin::BI__builtin_fabsf;
8436 case Builtin::BIabs:
8437 case Builtin::BIlabs:
8438 case Builtin::BIllabs:
8439 case Builtin::BIcabsf:
8440 case Builtin::BIcabs:
8441 case Builtin::BIcabsl:
8442 return Builtin::BIfabsf;
8448 case Builtin::BI__builtin_abs:
8449 case Builtin::BI__builtin_labs:
8450 case Builtin::BI__builtin_llabs:
8451 case Builtin::BI__builtin_fabsf:
8452 case Builtin::BI__builtin_fabs:
8453 case Builtin::BI__builtin_fabsl:
8454 return Builtin::BI__builtin_cabsf;
8455 case Builtin::BIabs:
8456 case Builtin::BIlabs:
8457 case Builtin::BIllabs:
8458 case Builtin::BIfabsf:
8459 case Builtin::BIfabs:
8460 case Builtin::BIfabsl:
8461 return Builtin::BIcabsf;
8464 llvm_unreachable(
"Unable to convert function");
8475 case Builtin::BI__builtin_abs:
8476 case Builtin::BI__builtin_fabs:
8477 case Builtin::BI__builtin_fabsf:
8478 case Builtin::BI__builtin_fabsl:
8479 case Builtin::BI__builtin_labs:
8480 case Builtin::BI__builtin_llabs:
8481 case Builtin::BI__builtin_cabs:
8482 case Builtin::BI__builtin_cabsf:
8483 case Builtin::BI__builtin_cabsl:
8484 case Builtin::BIabs:
8485 case Builtin::BIlabs:
8486 case Builtin::BIllabs:
8487 case Builtin::BIfabs:
8488 case Builtin::BIfabsf:
8489 case Builtin::BIfabsl:
8490 case Builtin::BIcabs:
8491 case Builtin::BIcabsf:
8492 case Builtin::BIcabsl:
8495 llvm_unreachable(
"Unknown Builtin type");
8501 unsigned AbsKind,
QualType ArgType) {
8502 bool EmitHeaderHint =
true;
8503 const char *HeaderName =
nullptr;
8504 StringRef FunctionName;
8506 FunctionName =
"std::abs";
8508 HeaderName =
"cstdlib";
8510 HeaderName =
"cmath";
8512 llvm_unreachable(
"Invalid Type");
8521 for (
const auto *I : R) {
8524 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
8526 FDecl = dyn_cast<FunctionDecl>(I);
8541 EmitHeaderHint =
false;
8559 EmitHeaderHint =
false;
8563 }
else if (!R.
empty()) {
8569 S.
Diag(
Loc, diag::note_replace_abs_function)
8575 if (!EmitHeaderHint)
8578 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
8582 template <std::
size_t StrLen>
8584 const char (&Str)[StrLen]) {
8597 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
8598 return std::any_of(names.begin(), names.end(), [&](llvm::StringRef
name) {
8599 return calleeName == name;
8605 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
8606 "__builtin_nanf16",
"__builtin_nanf128"});
8608 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
8609 "__builtin_inff16",
"__builtin_inff128"});
8611 llvm_unreachable(
"unknown MathCheck");
8614 void Sema::CheckInfNaNFunction(
const CallExpr *Call,
8618 bool IsNaNOrIsUnordered =
8622 if ((IsNaNOrIsUnordered || IsSpecialNaN) && FPO.getNoHonorNaNs()) {
8623 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8624 << 1 << 0 <<
Call->getSourceRange();
8626 bool IsInfOrIsFinite =
8628 bool IsInfinityOrIsSpecialInf =
8629 HasIdentifier && ((FDecl->
getName() ==
"infinity") ||
8631 if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs())
8632 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8633 << 0 << 0 <<
Call->getSourceRange();
8637 void Sema::CheckAbsoluteValueFunction(
const CallExpr *Call,
8639 if (
Call->getNumArgs() != 1)
8644 if (AbsKind == 0 && !IsStdAbs)
8647 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8653 StringRef FunctionName =
8655 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8656 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8665 unsigned DiagType = 0;
8671 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8685 if (ArgValueKind == ParamValueKind) {
8690 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8691 << FDecl << ArgType << ParamType;
8693 if (NewAbsKind == 0)
8697 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8706 if (NewAbsKind == 0)
8709 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8710 << FDecl << ParamValueKind << ArgValueKind;
8713 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8717 void Sema::CheckMaxUnsignedZero(
const CallExpr *Call,
8719 if (!Call || !FDecl)
return;
8722 if (inTemplateInstantiation())
return;
8723 if (
Call->getExprLoc().isMacroID())
return;
8726 if (
Call->getNumArgs() != 2)
return;
8729 if (!ArgList)
return;
8730 if (ArgList->size() != 1)
return;
8733 const auto& TA = ArgList->get(0);
8739 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
8740 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8741 if (!MTE)
return false;
8742 const auto *Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8743 if (!Num)
return false;
8744 if (Num->getValue() != 0)
return false;
8748 const Expr *FirstArg =
Call->getArg(0);
8749 const Expr *SecondArg =
Call->getArg(1);
8750 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
8751 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
8754 if (IsFirstArgZero == IsSecondArgZero)
return;
8759 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8761 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8762 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8766 if (IsFirstArgZero) {
8774 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8794 if (!Size->isComparisonOp() && !Size->isLogicalOp())
8798 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8799 << SizeRange << FnName;
8800 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8805 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8816 bool &IsContained) {
8819 IsContained =
false;
8832 for (
auto *FD : RD->
fields()) {
8845 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8846 if (Unary->getKind() == UETT_SizeOf)
8855 if (!
SizeOf->isArgumentType())
8856 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8863 return SizeOf->getTypeOfArgument();
8869 struct SearchNonTrivialToInitializeField
8874 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8878 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8879 asDerived().visitArray(PDIK, AT, SL);
8883 Super::visitWithKind(PDIK, FT, SL);
8898 visit(getContext().getBaseElementType(AT), SL);
8903 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8912 struct SearchNonTrivialToCopyField
8916 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8920 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8921 asDerived().visitArray(PCK, AT, SL);
8925 Super::visitWithKind(PCK, FT, SL);
8940 visit(getContext().getBaseElementType(AT), SL);
8963 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8964 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8988 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8990 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8991 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8997 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
9000 const Expr *SizeArg =
9001 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
9003 auto isLiteralZero = [](
const Expr *
E) {
9004 return (isa<IntegerLiteral>(
E) &&
9005 cast<IntegerLiteral>(
E)->getValue() == 0) ||
9006 (isa<CharacterLiteral>(
E) &&
9007 cast<CharacterLiteral>(
E)->getValue() == 0);
9013 if (isLiteralZero(SizeArg) &&
9020 if (BId == Builtin::BIbzero ||
9023 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
9024 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
9025 }
else if (!isLiteralZero(Call->getArg(1)->IgnoreImpCasts())) {
9026 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
9027 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
9035 if (BId == Builtin::BImemset &&
9039 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
9040 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
9045 void Sema::CheckMemaccessArguments(
const CallExpr *Call,
9052 unsigned ExpectedNumArgs =
9053 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
9054 if (
Call->getNumArgs() < ExpectedNumArgs)
9057 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
9058 BId == Builtin::BIstrndup ? 1 : 2);
9060 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
9061 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
9064 Call->getBeginLoc(),
Call->getRParenLoc()))
9073 llvm::FoldingSetNodeID SizeOfArgID;
9078 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9082 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
9083 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
9101 !Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
9105 if (SizeOfArgID == llvm::FoldingSetNodeID())
9106 SizeOfArg->
Profile(SizeOfArgID, Context,
true);
9107 llvm::FoldingSetNodeID DestID;
9108 Dest->
Profile(DestID, Context,
true);
9109 if (DestID == SizeOfArgID) {
9112 unsigned ActionIdx = 0;
9113 StringRef ReadableName = FnName->
getName();
9115 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
9116 if (UnaryOp->getOpcode() == UO_AddrOf)
9130 if (
SM.isMacroArgExpansion(SL)) {
9132 SL =
SM.getSpellingLoc(SL);
9139 DiagRuntimeBehavior(SL, SizeOfArg,
9140 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
9146 DiagRuntimeBehavior(SL, SizeOfArg,
9147 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
9161 DiagRuntimeBehavior(LenExpr->
getExprLoc(), Dest,
9162 PDiag(diag::warn_sizeof_pointer_type_memaccess)
9163 << FnName << SizeOfArgTy << ArgIdx
9181 unsigned OperationType = 0;
9182 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
9185 if (ArgIdx != 0 || IsCmp) {
9186 if (BId == Builtin::BImemcpy)
9188 else if(BId == Builtin::BImemmove)
9194 DiagRuntimeBehavior(Dest->
getExprLoc(), Dest,
9195 PDiag(diag::warn_dyn_class_memaccess)
9196 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
9197 << IsContained << ContainedRD << OperationType
9198 <<
Call->getCallee()->getSourceRange());
9200 BId != Builtin::BImemset)
9201 DiagRuntimeBehavior(
9203 PDiag(diag::warn_arc_object_memaccess)
9204 << ArgIdx << FnName << PointeeTy
9205 <<
Call->getCallee()->getSourceRange());
9207 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9208 RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
9209 DiagRuntimeBehavior(Dest->
getExprLoc(), Dest,
9210 PDiag(diag::warn_cstruct_memaccess)
9211 << ArgIdx << FnName << PointeeTy << 0);
9212 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
9213 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9214 RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
9215 DiagRuntimeBehavior(Dest->
getExprLoc(), Dest,
9216 PDiag(diag::warn_cstruct_memaccess)
9217 << ArgIdx << FnName << PointeeTy << 1);
9218 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
9225 DiagRuntimeBehavior(
9227 PDiag(diag::note_bad_memaccess_silence)
9247 if (isa<IntegerLiteral>(RHS))
9249 else if (isa<IntegerLiteral>(LHS))
9263 if (CAT->getZExtSize() <= 1)
9271 void Sema::CheckStrlcpycatArguments(
const CallExpr *Call,
9275 unsigned NumArgs =
Call->getNumArgs();
9276 if ((NumArgs != 3) && (NumArgs != 4))
9281 const Expr *CompareWithSrc =
nullptr;
9284 Call->getBeginLoc(),
Call->getRParenLoc()))
9289 CompareWithSrc = Ex;
9292 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
9293 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
9294 SizeCall->getNumArgs() == 1)
9299 if (!CompareWithSrc)
9306 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
9310 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
9311 if (!CompareWithSrcDRE ||
9315 const Expr *OriginalSizeArg =
Call->getArg(2);
9316 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
9323 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
9328 llvm::raw_svector_ostream OS(sizeString);
9330 DstArg->
printPretty(OS,
nullptr, getPrintingPolicy());
9333 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
9340 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
9341 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
9342 return D1->getDecl() == D2->getDecl();
9347 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
9351 return CE->getArg(0)->IgnoreParenCasts();
9356 void Sema::CheckStrncatArguments(
const CallExpr *CE,
9371 unsigned PatternType = 0;
9379 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
9380 if (BE->getOpcode() == BO_Sub) {
9393 if (PatternType == 0)
9402 if (
SM.isMacroArgExpansion(SL)) {
9403 SL =
SM.getSpellingLoc(SL);
9412 if (!isKnownSizeArray) {
9413 if (PatternType == 1)
9414 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9416 Diag(SL, diag::warn_strncat_src_size) << SR;
9420 if (PatternType == 1)
9421 Diag(SL, diag::warn_strncat_large_size) << SR;
9423 Diag(SL, diag::warn_strncat_src_size) << SR;
9426 llvm::raw_svector_ostream OS(sizeString);
9428 DstArg->
printPretty(OS,
nullptr, getPrintingPolicy());
9431 DstArg->
printPretty(OS,
nullptr, getPrintingPolicy());
9434 Diag(SL, diag::note_strncat_wrong_size)
9439 void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
9441 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9443 << CalleeName << 0 << cast<NamedDecl>(
D);
9448 void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
9450 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9451 const Decl *
D = Lvalue->getDecl();
9452 if (isa<DeclaratorDecl>(
D))
9453 if (!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9454 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9457 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9458 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9459 Lvalue->getMemberDecl());
9462 void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
9464 const auto *Lambda = dyn_cast<LambdaExpr>(
9469 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9470 << CalleeName << 2 ;
9473 void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
9475 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9480 << CalleeName << 0 << Var;
9483 void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
9486 llvm::raw_svector_ostream OS(SizeString);
9489 if (
Kind == clang::CK_BitCast &&
9490 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
9492 if (
Kind == clang::CK_IntegralToPointer &&
9493 !isa<IntegerLiteral>(
9494 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9497 switch (
Cast->getCastKind()) {
9498 case clang::CK_BitCast:
9499 case clang::CK_IntegralToPointer:
9500 case clang::CK_FunctionToPointerDecay:
9509 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9510 << CalleeName << 0 << OS.str();
9514 void Sema::CheckFreeArguments(
const CallExpr *
E) {
9515 const std::string CalleeName =
9516 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9520 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9522 case UnaryOperator::Opcode::UO_AddrOf:
9523 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9524 case UnaryOperator::Opcode::UO_Plus:
9525 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9530 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
9532 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9534 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
9535 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9536 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
9540 if (isa<BlockExpr>(Arg)) {
9542 << CalleeName << 1 ;
9547 if (
const auto *
Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9548 return CheckFreeArgumentsCast(*
this, CalleeName,
Cast);
9552 Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
9558 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9561 Diag(ReturnLoc, diag::warn_null_ret)
9571 if (Op == OO_New || Op == OO_Array_New) {
9576 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9577 << FD << getLangOpts().CPlusPlus11;
9582 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9588 PPC().CheckPPCMMAType(RetValExp->
getType(), ReturnLoc);
9599 auto getCastAndLiteral = [&FPLiteral, &FPCast](
Expr *L,
Expr *R) {
9600 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9602 return FPLiteral && FPCast;
9605 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9613 llvm::APFloat::rmNearestTiesToEven, &Lossy);
9617 Diag(
Loc, diag::warn_float_compare_literal)
9631 if (
auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9632 if (
auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9633 if (DRL->getDecl() == DRR->getDecl())
9641 if (
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9645 if (
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9650 if (
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9651 if (CL->getBuiltinCallee())
9654 if (
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9655 if (CR->getBuiltinCallee())
9659 Diag(
Loc, diag::warn_floatingpoint_eq)
9680 IntRange(
unsigned Width,
bool NonNegative)
9681 : Width(Width), NonNegative(NonNegative) {}
9684 unsigned valueBits()
const {
9685 return NonNegative ? Width : Width - 1;
9689 static IntRange forBoolType() {
9690 return IntRange(1,
true);
9695 return forValueOfCanonicalType(C,
9700 static IntRange forValueOfCanonicalType(
ASTContext &C,
const Type *
T) {
9703 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9704 T = VT->getElementType().getTypePtr();
9706 T = CT->getElementType().getTypePtr();
9707 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9708 T = AT->getValueType().getTypePtr();
9710 if (!
C.getLangOpts().CPlusPlus) {
9712 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9713 T = ET->getDecl()->getIntegerType().getDesugaredType(C).getTypePtr();
9714 }
else if (
const EnumType *ET = dyn_cast<EnumType>(
T)) {
9719 if (
Enum->isFixed()) {
9720 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
9724 unsigned NumPositive =
Enum->getNumPositiveBits();
9725 unsigned NumNegative =
Enum->getNumNegativeBits();
9727 if (NumNegative == 0)
9728 return IntRange(NumPositive,
true);
9730 return IntRange(
std::max(NumPositive + 1, NumNegative),
9734 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9735 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9748 static IntRange forTargetOfCanonicalType(
ASTContext &C,
const Type *
T) {
9751 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9752 T = VT->getElementType().getTypePtr();
9754 T = CT->getElementType().getTypePtr();
9755 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9756 T = AT->getValueType().getTypePtr();
9757 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9758 T =
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9760 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9761 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9770 static IntRange join(IntRange L, IntRange R) {
9771 bool Unsigned = L.NonNegative && R.NonNegative;
9772 return IntRange(
std::max(L.valueBits(), R.valueBits()) + !Unsigned,
9773 L.NonNegative && R.NonNegative);
9777 static IntRange bit_and(IntRange L, IntRange R) {
9778 unsigned Bits =
std::max(L.Width, R.Width);
9779 bool NonNegative =
false;
9780 if (L.NonNegative) {
9784 if (R.NonNegative) {
9788 return IntRange(Bits, NonNegative);
9792 static IntRange sum(IntRange L, IntRange R) {
9793 bool Unsigned = L.NonNegative && R.NonNegative;
9794 return IntRange(
std::max(L.valueBits(), R.valueBits()) + 1 + !Unsigned,
9799 static IntRange difference(IntRange L, IntRange R) {
9803 bool CanWiden = !L.NonNegative || !R.NonNegative;
9804 bool Unsigned = L.NonNegative && R.Width == 0;
9805 return IntRange(
std::max(L.valueBits(), R.valueBits()) + CanWiden +
9811 static IntRange product(IntRange L, IntRange R) {
9815 bool CanWiden = !L.NonNegative && !R.NonNegative;
9816 bool Unsigned = L.NonNegative && R.NonNegative;
9817 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !Unsigned,
9822 static IntRange rem(IntRange L, IntRange R) {
9826 return IntRange(
std::min(L.valueBits(), R.valueBits()) + !Unsigned,
9834 unsigned MaxWidth) {
9835 if (value.isSigned() && value.isNegative())
9836 return IntRange(value.getSignificantBits(),
false);
9838 if (value.getBitWidth() > MaxWidth)
9839 value = value.trunc(MaxWidth);
9843 return IntRange(value.getActiveBits(),
true);
9847 unsigned MaxWidth) {
9855 R = IntRange::join(R, El);
9863 return IntRange::join(R, I);
9878 Ty = AtomicRHS->getValueType();
9891 bool InConstantContext,
bool Approximate) {
9902 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
9903 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9904 return GetExprRange(C, CE->getSubExpr(), MaxWidth, InConstantContext,
9907 IntRange OutputTypeRange = IntRange::forValueOfType(C,
GetExprType(CE));
9909 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9910 CE->getCastKind() == CK_BooleanToSignedIntegral;
9914 return OutputTypeRange;
9917 std::min(MaxWidth, OutputTypeRange.Width),
9918 InConstantContext, Approximate);
9921 if (SubRange.Width >= OutputTypeRange.Width)
9922 return OutputTypeRange;
9926 return IntRange(SubRange.Width,
9927 SubRange.NonNegative || OutputTypeRange.NonNegative);
9930 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
9933 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult, C))
9935 CondResult ? CO->getTrueExpr() : CO->getFalseExpr(),
9936 MaxWidth, InConstantContext, Approximate);
9941 Expr *
E = CO->getTrueExpr();
9944 :
GetExprRange(C,
E, MaxWidth, InConstantContext, Approximate);
9945 E = CO->getFalseExpr();
9948 :
GetExprRange(C,
E, MaxWidth, InConstantContext, Approximate);
9949 return IntRange::join(L, R);
9952 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
9953 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9955 switch (BO->getOpcode()) {
9957 llvm_unreachable(
"builtin <=> should have class type");
9968 return IntRange::forBoolType();
9986 return GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext,
9997 Combine = IntRange::bit_and;
10005 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
10006 if (I->getValue() == 1) {
10007 IntRange R = IntRange::forValueOfType(C,
GetExprType(
E));
10008 return IntRange(R.Width,
true);
10018 case BO_ShrAssign: {
10019 IntRange L =
GetExprRange(C, BO->getLHS(), MaxWidth, InConstantContext,
10024 if (std::optional<llvm::APSInt> shift =
10025 BO->getRHS()->getIntegerConstantExpr(C)) {
10026 if (shift->isNonNegative()) {
10027 if (shift->uge(L.Width))
10028 L.Width = (L.NonNegative ? 0 : 1);
10030 L.Width -= shift->getZExtValue();
10039 return GetExprRange(C, BO->getRHS(), MaxWidth, InConstantContext,
10044 Combine = IntRange::sum;
10048 if (BO->getLHS()->getType()->isPointerType())
10051 Combine = IntRange::difference;
10056 Combine = IntRange::product;
10064 IntRange L =
GetExprRange(C, BO->getLHS(), opWidth, InConstantContext,
10068 if (std::optional<llvm::APSInt> divisor =
10069 BO->getRHS()->getIntegerConstantExpr(C)) {
10070 unsigned log2 = divisor->logBase2();
10071 if (
log2 >= L.Width)
10072 L.Width = (L.NonNegative ? 0 : 1);
10081 IntRange R =
GetExprRange(C, BO->getRHS(), opWidth, InConstantContext,
10083 return IntRange(L.Width, L.NonNegative && R.NonNegative);
10087 Combine = IntRange::rem;
10099 unsigned opWidth = C.getIntWidth(
T);
10101 GetExprRange(C, BO->getLHS(), opWidth, InConstantContext, Approximate);
10103 GetExprRange(C, BO->getRHS(), opWidth, InConstantContext, Approximate);
10104 IntRange C = Combine(L, R);
10106 C.Width =
std::min(C.Width, MaxWidth);
10110 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
10111 switch (UO->getOpcode()) {
10114 return IntRange::forBoolType();
10122 return GetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
10127 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
10128 return GetExprRange(C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
10132 return IntRange(BitField->getBitWidthValue(C),
10133 BitField->getType()->isUnsignedIntegerOrEnumerationType());
10139 bool InConstantContext,
bool Approximate) {
10148 const llvm::fltSemantics &Src,
10149 const llvm::fltSemantics &Tgt) {
10153 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
10154 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
10156 return truncated.bitwiseIsEqual(value);
10165 const llvm::fltSemantics &Src,
10166 const llvm::fltSemantics &Tgt) {
10183 bool IsListInit =
false);
10189 if (isa<EnumConstantDecl>(DR->getDecl()))
10199 return MacroName !=
"YES" && MacroName !=
"NO" &&
10200 MacroName !=
"true" && MacroName !=
"false";
10223 struct PromotedRange {
10229 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
10231 PromotedMin = PromotedMax =
llvm::APSInt(BitWidth, Unsigned);
10232 else if (R.Width >= BitWidth && !Unsigned) {
10236 PromotedMin = llvm::APSInt::getMinValue(BitWidth, Unsigned);
10237 PromotedMax = llvm::APSInt::getMaxValue(BitWidth, Unsigned);
10239 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
10240 .extOrTrunc(BitWidth);
10241 PromotedMin.setIsUnsigned(Unsigned);
10243 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
10244 .extOrTrunc(BitWidth);
10245 PromotedMax.setIsUnsigned(Unsigned);
10250 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
10260 InRangeFlag = 0x40,
10263 Min =
LE | InRangeFlag,
10265 Max =
GE | InRangeFlag,
10268 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
10273 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
10274 Value.isUnsigned() == PromotedMin.isUnsigned());
10275 if (!isContiguous()) {
10276 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
10277 if (
Value.isMinValue())
return Min;
10278 if (
Value.isMaxValue())
return Max;
10284 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
10285 case -1:
return Less;
10286 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
10288 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
10290 case 0:
return Max;
10295 llvm_unreachable(
"impossible compare result");
10298 static std::optional<StringRef>
10300 if (Op == BO_Cmp) {
10302 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
10304 if (R &
EQ)
return StringRef(
"'std::strong_ordering::equal'");
10305 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
10306 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
10307 return std::nullopt;
10314 }
else if (Op == BO_NE) {
10318 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
10325 if (Op == BO_GE || Op == BO_LE)
10326 std::swap(TrueFlag, FalseFlag);
10329 return StringRef(
"true");
10331 return StringRef(
"false");
10332 return std::nullopt;
10340 if (ICE->getCastKind() != CK_IntegralCast &&
10341 ICE->getCastKind() != CK_NoOp)
10343 E = ICE->getSubExpr();
10352 enum ConstantValueKind {
10357 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
10358 return BL->getValue() ? ConstantValueKind::LiteralTrue
10359 : ConstantValueKind::LiteralFalse;
10360 return ConstantValueKind::Miscellaneous;
10366 bool RhsConstant) {
10391 OtherT = AT->getValueType();
10392 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
10396 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
10402 bool OtherIsBooleanDespiteType =
10404 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
10405 OtherTypeRange = OtherValueRange = IntRange::forBoolType();
10409 PromotedRange OtherPromotedValueRange(OtherValueRange,
Value.getBitWidth(),
10410 Value.isUnsigned());
10411 auto Cmp = OtherPromotedValueRange.compare(
Value);
10412 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10418 bool TautologicalTypeCompare =
false;
10420 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10421 Value.isUnsigned());
10422 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
10423 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10425 TautologicalTypeCompare =
true;
10433 if (!TautologicalTypeCompare && OtherValueRange.Width == 0)
10442 bool InRange = Cmp & PromotedRange::InRangeFlag;
10449 Other->getType()->isUnsignedIntegerOrEnumerationType())
10450 TautologicalTypeCompare =
true;
10455 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
10456 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10460 llvm::raw_svector_ostream OS(PrettySourceValue);
10462 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
10463 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
10465 OS << (BL->getValue() ?
"YES" :
"NO");
10470 if (!TautologicalTypeCompare) {
10471 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10472 << RhsConstant << OtherValueRange.Width << OtherValueRange.NonNegative
10473 <<
E->getOpcodeStr() << OS.str() << *Result
10478 if (IsObjCSignedCharBool) {
10480 S.
PDiag(diag::warn_tautological_compare_objc_bool)
10481 << OS.str() << *Result);
10491 E->getOperatorLoc(),
E,
10493 : diag::warn_tautological_bool_compare)
10495 << OtherIsBooleanDespiteType << *Result
10502 ? diag::warn_unsigned_enum_always_true_comparison
10503 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10504 : diag::warn_unsigned_always_true_comparison)
10505 : diag::warn_tautological_constant_compare;
10508 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *Result
10538 Expr *LHS =
E->getLHS();
10539 Expr *RHS =
E->getRHS();
10542 std::optional<llvm::APSInt> RHSValue =
10544 std::optional<llvm::APSInt> LHSValue =
10548 if (RHSValue && LHSValue)
10552 if ((
bool)RHSValue ^ (
bool)LHSValue) {
10554 const bool RhsConstant = (
bool)RHSValue;
10555 Expr *Const = RhsConstant ? RHS : LHS;
10580 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10582 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10588 Expr *signedOperand, *unsignedOperand;
10591 "unsigned comparison between two signed integer expressions?");
10592 signedOperand = LHS;
10593 unsignedOperand = RHS;
10595 signedOperand = RHS;
10596 unsignedOperand = LHS;
10602 IntRange signedRange =
10612 if (signedRange.NonNegative)
10619 if (
E->isEqualityOp()) {
10621 IntRange unsignedRange =
10627 assert(unsignedRange.NonNegative &&
"unsigned range includes negative?");
10629 if (unsignedRange.Width < comparisonWidth)
10634 S.
PDiag(diag::warn_mixed_sign_comparison)
10662 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10663 << BitfieldEnumDecl;
10670 Init->isValueDependent() ||
10671 Init->isTypeDependent())
10674 Expr *OriginalInit = Init->IgnoreParenImpCasts();
10697 unsigned DiagID = 0;
10698 if (SignedEnum && !SignedBitfield) {
10699 DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10700 }
else if (SignedBitfield && !SignedEnum &&
10702 DiagID = diag::warn_signed_bitfield_enum_conversion;
10706 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10711 << SignedEnum << TypeRange;
10722 if (BitsNeeded > FieldWidth) {
10724 S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10736 unsigned OriginalWidth =
Value.getBitWidth();
10742 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
10743 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10750 if (!
Value.isSigned() ||
Value.isNegative())
10751 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
10752 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10753 OriginalWidth =
Value.getSignificantBits();
10755 if (OriginalWidth <= FieldWidth)
10763 TruncatedValue = TruncatedValue.extend(OriginalWidth);
10764 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
10768 std::string PrettyTrunc =
toString(TruncatedValue, 10);
10770 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10771 ? diag::warn_impcast_single_bit_bitield_precision_constant
10772 : diag::warn_impcast_bitfield_precision_constant)
10773 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
10774 << Init->getSourceRange();
10789 E->getOperatorLoc())) {
10792 E->getOperatorLoc());
10806 bool pruneControlFlow =
false) {
10807 if (pruneControlFlow) {
10821 unsigned diag,
bool pruneControlFlow =
false) {
10834 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10837 const bool IsLiteral =
10838 isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10846 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10851 diag::warn_impcast_float_integer, PruneWarnings);
10854 bool isExact =
false;
10858 llvm::APFloat::opStatus Result =
Value.convertToInteger(
10859 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10867 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10868 precision = (precision * 59 + 195) / 196;
10869 Value.toString(PrettySourceValue, precision);
10873 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10874 << PrettySourceValue);
10877 if (Result == llvm::APFloat::opOK && isExact) {
10878 if (IsLiteral)
return;
10885 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
10888 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10889 : diag::warn_impcast_float_to_integer_out_of_range,
10892 unsigned DiagID = 0;
10895 DiagID = diag::warn_impcast_literal_float_to_integer;
10896 }
else if (IntegerValue == 0) {
10897 if (
Value.isZero()) {
10899 diag::warn_impcast_float_integer, PruneWarnings);
10902 DiagID = diag::warn_impcast_float_to_integer_zero;
10904 if (IntegerValue.isUnsigned()) {
10905 if (!IntegerValue.isMaxValue()) {
10907 diag::warn_impcast_float_integer, PruneWarnings);
10910 if (!IntegerValue.isMaxSignedValue() &&
10911 !IntegerValue.isMinSignedValue()) {
10913 diag::warn_impcast_float_integer, PruneWarnings);
10917 DiagID = diag::warn_impcast_float_to_integer;
10922 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
10924 IntegerValue.toString(PrettyTargetValue);
10926 if (PruneWarnings) {
10929 <<
E->
getType() <<
T.getUnqualifiedType()
10930 << PrettySourceValue << PrettyTargetValue
10934 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10942 assert(isa<CompoundAssignOperator>(
E) &&
10943 "Must be compound assignment operation");
10949 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10953 const auto *RBT = cast<CompoundAssignOperator>(
E)
10954 ->getComputationResultType()
10961 if (ResultBT->isInteger())
10963 E->
getExprLoc(), diag::warn_impcast_float_integer);
10965 if (!ResultBT->isFloatingPoint())
10974 diag::warn_impcast_float_result_precision);
10979 if (!
Range.Width)
return "0";
10982 ValueInRange.setIsSigned(!
Range.NonNegative);
10983 ValueInRange = ValueInRange.trunc(
Range.Width);
10984 return toString(ValueInRange, 10);
10988 if (!isa<ImplicitCastExpr>(Ex))
10993 const Type *Source =
10995 if (
Target->isDependentType())
10999 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
11000 const Type *BoolCandidateType = ToBool ?
Target : Source;
11009 for (
unsigned i = 0; i < NumArgs; ++i) {
11014 bool IsSwapped = ((i > 0) &&
11016 IsSwapped |= ((i < (NumArgs - 1)) &&
11022 diag::warn_impcast_floating_point_to_bool);
11029 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
11034 if (isa<CallExpr>(
E))
11039 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
11041 if (!IsGNUNullExpr && !HasNullPtrType)
11061 if (MacroName ==
"NULL")
11069 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
11083 const char FirstLiteralCharacter =
11085 if (FirstLiteralCharacter ==
'0')
11092 const char FirstContextCharacter =
11094 if (FirstContextCharacter ==
'{')
11102 const auto *IL = dyn_cast<IntegerLiteral>(
E);
11104 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
11105 if (UO->getOpcode() == UO_Minus)
11106 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
11117 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
11121 if (Opc == BO_Shl) {
11124 if (LHS && LHS->getValue() == 0)
11125 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
11127 RHS->getValue().isNonNegative() &&
11129 S.
Diag(ExprLoc, diag::warn_left_shift_always)
11130 << (Result.Val.getInt() != 0);
11132 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
11136 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
11141 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
11142 (RHS->getValue() == 0 || RHS->getValue() == 1))
11145 if (LHS->getValue() != 0 && RHS->getValue() != 0)
11146 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
11151 bool *ICContext,
bool IsListInit) {
11156 if (Source ==
Target)
return;
11157 if (
Target->isDependentType())
return;
11171 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
11172 if (isa<StringLiteral>(
E))
11177 diag::warn_impcast_string_literal_to_bool);
11178 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
11179 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
11183 diag::warn_impcast_objective_c_literal_to_bool);
11198 if (Result.Val.getInt() != 1 && Result.Val.getInt() != 0) {
11199 ObjC().adornBoolConversionDiagWithTernaryFixit(
11200 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
11201 <<
toString(Result.Val.getInt(), 10));
11209 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
11211 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
11212 ObjC().checkDictionaryLiteral(
QualType(
Target, 0), DictionaryLiteral);
11215 if (isa<VectorType>(Source)) {
11216 if (
Target->isSveVLSBuiltinType() &&
11223 if (
Target->isRVVVLSBuiltinType() &&
11230 if (!isa<VectorType>(
Target)) {
11231 if (SourceMgr.isInSystemMacro(CC))
11234 }
else if (getLangOpts().
HLSL &&
11240 diag::warn_hlsl_impcast_vector_truncation);
11245 if (!getLangOpts().
HLSL &&
11249 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
11250 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
11252 if (
auto VecTy = dyn_cast<VectorType>(
Target))
11253 Target = VecTy->getElementType().getTypePtr();
11256 if (isa<ComplexType>(Source)) {
11257 if (!isa<ComplexType>(
Target)) {
11258 if (SourceMgr.isInSystemMacro(CC) ||
Target->isBooleanType())
11263 ? diag::err_impcast_complex_scalar
11264 : diag::warn_impcast_complex_scalar);
11267 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
11268 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
11271 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
11303 int Order = getASTContext().getFloatingTypeSemanticOrder(
11315 if (getLangOpts().SYCLIsDevice)
11316 SYCL().DiagIfDeviceCode(CC, diag::warn_imp_float_size_conversion);
11319 diag::warn_imp_float_size_conversion);
11324 if (SourceMgr.isInSystemMacro(CC))
11330 if (Diags.isIgnored(diag::warn_impcast_float_precision, CC)) {
11331 if (getLangOpts().SYCLIsDevice)
11332 SYCL().DiagIfDeviceCode(CC, diag::warn_imp_float_size_conversion);
11335 diag::warn_imp_float_size_conversion);
11340 else if (Order < 0) {
11341 if (SourceMgr.isInSystemMacro(CC))
11350 if (TargetBT && TargetBT->
isInteger()) {
11351 if (SourceMgr.isInSystemMacro(CC))
11365 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
11373 if (isa<ImplicitCastExpr>(LastA) &&
11377 diag::warn_impcast_floating_point_to_bool);
11386 if (
Target->isUnsaturatedFixedPointType()) {
11389 isConstantEvaluatedContext())) {
11390 llvm::APFixedPoint
Value = Result.Val.getFixedPoint();
11395 PDiag(diag::warn_impcast_fixed_point_range)
11396 <<
Value.toString() <<
T
11402 }
else if (
Target->isIntegerType()) {
11404 if (!isConstantEvaluatedContext() &&
11406 llvm::APFixedPoint FXResult = Result.Val.getFixedPoint();
11415 PDiag(diag::warn_impcast_fixed_point_range)
11416 << FXResult.toString() <<
T
11423 }
else if (
Target->isUnsaturatedFixedPointType()) {
11426 if (!isConstantEvaluatedContext() &&
11431 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11436 PDiag(diag::warn_impcast_fixed_point_range)
11455 unsigned int SourcePrecision =
SourceRange.Width;
11459 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
11462 if (SourcePrecision > 0 && TargetPrecision > 0 &&
11463 SourcePrecision > TargetPrecision) {
11465 if (std::optional<llvm::APSInt> SourceInt =
11472 llvm::APFloat::opStatus ConversionStatus =
11473 TargetFloatValue.convertFromAPInt(
11475 llvm::APFloat::rmNearestTiesToEven);
11477 if (ConversionStatus != llvm::APFloat::opOK) {
11479 SourceInt->toString(PrettySourceValue, 10);
11481 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11483 DiagRuntimeBehavior(
11485 PDiag(diag::warn_impcast_integer_float_precision_constant)
11486 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11492 diag::warn_impcast_integer_float_precision);
11499 DiscardMisalignedMemberAddress(
Target,
E);
11501 if (
Target->isBooleanType())
11509 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
11512 if (ObjC().isSignedCharBool(
T) && !Source->
isCharType() &&
11514 return ObjC().adornBoolConversionDiagWithTernaryFixit(
11515 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11519 IntRange SourceTypeRange =
11520 IntRange::forTargetOfCanonicalType(Context, Source);
11522 Context,
E, isConstantEvaluatedContext(),
true);
11523 IntRange TargetRange = IntRange::forTargetOfCanonicalType(Context,
Target);
11525 if (LikelySourceRange.Width > TargetRange.Width) {
11530 isConstantEvaluatedContext())) {
11532 Value = Result.Val.getInt();
11534 if (SourceMgr.isInSystemMacro(CC))
11541 PDiag(diag::warn_impcast_integer_precision_constant)
11542 << PrettySourceValue << PrettyTargetValue
11549 if (SourceMgr.isInSystemMacro(CC))
11556 diag::warn_impcast_integer_precision);
11559 if (TargetRange.Width > SourceTypeRange.Width) {
11560 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
11561 if (UO->getOpcode() == UO_Minus)
11563 if (
Target->isUnsignedIntegerType())
11565 diag::warn_impcast_high_order_zero_bits);
11566 if (
Target->isSignedIntegerType())
11568 diag::warn_impcast_nonnegative_result);
11572 if (TargetRange.Width == LikelySourceRange.Width &&
11573 !TargetRange.NonNegative && LikelySourceRange.NonNegative &&
11581 !SourceMgr.isInSystemMacro(CC)) {
11588 PDiag(diag::warn_impcast_integer_precision_constant)
11589 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11598 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11599 ((TargetRange.NonNegative && !LikelySourceRange.NonNegative) ||
11600 (!TargetRange.NonNegative && LikelySourceRange.NonNegative &&
11601 LikelySourceRange.Width == TargetRange.Width))) {
11602 if (SourceMgr.isInSystemMacro(CC))
11605 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
11611 unsigned DiagID = diag::warn_impcast_integer_sign;
11619 DiagID = diag::warn_impcast_integer_sign_conditional;
11634 if (SourceEnum->getDecl()->hasNameForLinkage() &&
11635 TargetEnum->getDecl()->hasNameForLinkage() &&
11636 SourceEnum != TargetEnum) {
11637 if (SourceMgr.isInSystemMacro(CC))
11641 diag::warn_impcast_different_enum_types);
11655 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
11667 Expr *TrueExpr =
E->getTrueExpr();
11668 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
11669 TrueExpr = BCO->getCommon();
11671 bool Suspicious =
false;
11680 if (!Suspicious)
return;
11683 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11690 Suspicious =
false;
11712 struct AnalyzeImplicitConversionsWorkItem {
11722 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11724 Expr *OrigE = Item.E;
11733 bool IsListInit = Item.IsListInit ||
11734 (isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11739 Expr *SourceExpr =
E;
11744 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11745 if (
auto *Src = OVE->getSourceExpr())
11748 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
11749 if (UO->getOpcode() == UO_Not &&
11750 UO->getSubExpr()->isKnownToHaveBooleanValue())
11751 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11755 if (
const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
11756 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11757 BO->getLHS()->isKnownToHaveBooleanValue() &&
11758 BO->getRHS()->isKnownToHaveBooleanValue() &&
11759 BO->getLHS()->HasSideEffects(S.
Context) &&
11760 BO->getRHS()->HasSideEffects(S.
Context)) {
11771 if (SR.str() ==
"&" || SR.str() ==
"|") {
11773 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11774 << (BO->getOpcode() == BO_And ?
"&" :
"|")
11777 BO->getOperatorLoc(),
11778 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
11779 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11785 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11791 if (
CallExpr *Call = dyn_cast<CallExpr>(SourceExpr))
11806 for (
auto *SE : POE->semantics())
11807 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11808 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11812 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
11816 WorkList.push_back({
E, CC, IsListInit});
11822 if (BO->isComparisonOp())
11826 if (BO->getOpcode() == BO_Assign)
11829 if (BO->isAssignmentOp())
11837 if (isa<StmtExpr>(
E))
return;
11840 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11845 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11847 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11851 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11852 if (ChildExpr == CSE->getOperand())
11858 if (IsLogicalAndOperator &&
11863 WorkList.push_back({ChildExpr, CC, IsListInit});
11868 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11872 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11877 if (
U->getOpcode() == UO_LNot) {
11879 }
else if (
U->getOpcode() != UO_AddrOf) {
11880 if (
U->getSubExpr()->getType()->isAtomicType())
11881 S.
Diag(
U->getSubExpr()->getBeginLoc(),
11882 diag::warn_atomic_implicit_seq_cst);
11893 WorkList.push_back({OrigE, CC, IsListInit});
11894 while (!WorkList.empty())
11906 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
11909 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11910 if (!M->getMemberDecl()->getType()->isReferenceType())
11912 }
else if (
const CallExpr *Call = dyn_cast<CallExpr>(
E)) {
11913 if (!Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11915 FD = Call->getDirectCallee();
11924 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11938 if (
SM.isMacroBodyExpansion(
Loc))
11940 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
11963 if (isa<CXXThisExpr>(
E)) {
11964 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
11965 : diag::warn_this_bool_conversion;
11970 bool IsAddressOf =
false;
11972 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11973 if (UO->getOpcode() != UO_AddrOf)
11975 IsAddressOf =
true;
11976 E = UO->getSubExpr();
11980 unsigned DiagID = IsCompare
11981 ? diag::warn_address_of_reference_null_compare
11982 : diag::warn_address_of_reference_bool_conversion;
11990 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
11991 bool IsParam = isa<NonNullAttr>(NonnullAttr);
11993 llvm::raw_string_ostream S(Str);
11995 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
11996 : diag::warn_cast_nonnull_to_bool;
11999 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
12004 if (
auto *Callee = Call->getDirectCallee()) {
12005 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
12006 ComplainAboutNonnullParamOrCall(A);
12014 if (!inTemplateInstantiation()) {
12015 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
12016 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
12017 MRecordDecl && MRecordDecl->isLambda()) {
12020 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
12030 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
12031 D = M->getMemberDecl();
12035 if (!
D ||
D->isWeak())
12039 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
12040 if (getCurFunction() &&
12041 !getCurFunction()->ModifiedNonNullParams.count(PV)) {
12042 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
12043 ComplainAboutNonnullParamOrCall(A);
12047 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
12051 auto ParamIter = llvm::find(FD->
parameters(), PV);
12057 ComplainAboutNonnullParamOrCall(
NonNull);
12062 if (ArgNo.getASTIndex() == ParamNo) {
12063 ComplainAboutNonnullParamOrCall(
NonNull);
12077 if (IsAddressOf && IsFunction) {
12082 if (!IsAddressOf && !IsFunction && !IsArray)
12087 llvm::raw_string_ostream S(Str);
12090 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
12091 : diag::warn_impcast_pointer_to_bool;
12098 DiagType = AddressOf;
12099 else if (IsFunction)
12100 DiagType = FunctionPointer;
12102 DiagType = ArrayPointer;
12104 llvm_unreachable(
"Could not determine diagnostic.");
12106 <<
Range << IsEqual;
12118 tryExprAsCall(*
E, ReturnType, NonTemplateOverloads);
12119 if (ReturnType.
isNull())
12147 if (isUnevaluatedContext())
12157 CheckArrayAccess(
E);
12167 void Sema::CheckForIntOverflow (
const Expr *
E) {
12172 const Expr *OriginalE = Exprs.pop_back_val();
12175 if (isa<BinaryOperator, UnaryOperator>(
E)) {
12180 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
12181 Exprs.append(InitList->inits().begin(), InitList->inits().end());
12182 else if (isa<ObjCBoxedExpr>(OriginalE))
12184 else if (
const auto *Call = dyn_cast<CallExpr>(
E))
12185 Exprs.append(
Call->arg_begin(),
Call->arg_end());
12186 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
12187 Exprs.append(Message->arg_begin(), Message->arg_end());
12188 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
12189 Exprs.append(Construct->arg_begin(), Construct->arg_end());
12190 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
12191 Exprs.push_back(Temporary->getSubExpr());
12192 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
12193 Exprs.push_back(
Array->getIdx());
12194 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
12195 Exprs.push_back(Compound->getInitializer());
12196 else if (
const auto *New = dyn_cast<CXXNewExpr>(
E);
12197 New && New->isArray()) {
12198 if (
auto ArraySize = New->getArraySize())
12199 Exprs.push_back(*ArraySize);
12201 }
while (!Exprs.empty());
12216 class SequenceTree {
12220 LLVM_PREFERRED_TYPE(
bool)
12221 unsigned Merged : 1;
12229 friend class SequenceTree;
12233 explicit Seq(
unsigned N) : Index(N) {}
12236 Seq() : Index(0) {}
12239 SequenceTree() { Values.push_back(
Value(0)); }
12240 Seq root()
const {
return Seq(0); }
12247 return Seq(Values.size() - 1);
12251 void merge(Seq S) {
12252 Values[S.Index].Merged =
true;
12258 bool isUnsequenced(Seq Cur, Seq Old) {
12259 unsigned C = representative(Cur.Index);
12260 unsigned Target = representative(Old.Index);
12264 C = Values[
C].Parent;
12271 unsigned representative(
unsigned K) {
12272 if (Values[K].Merged)
12274 return Values[K].Parent = representative(Values[K].
Parent);
12294 UK_ModAsSideEffect,
12296 UK_Count = UK_ModAsSideEffect + 1
12302 const Expr *UsageExpr =
nullptr;
12303 SequenceTree::Seq
Seq;
12309 Usage Uses[UK_Count];
12312 bool Diagnosed =
false;
12316 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
12324 UsageInfoMap UsageMap;
12327 SequenceTree::Seq Region;
12342 struct SequencedSubexpression {
12343 SequencedSubexpression(SequenceChecker &Self)
12344 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
12345 Self.ModAsSideEffect = &ModAsSideEffect;
12348 ~SequencedSubexpression() {
12349 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
12353 UsageInfo &UI = Self.UsageMap[M.first];
12354 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
12355 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
12356 SideEffectUsage = M.second;
12358 Self.ModAsSideEffect = OldModAsSideEffect;
12361 SequenceChecker &Self;
12370 class EvaluationTracker {
12372 EvaluationTracker(SequenceChecker &Self)
12373 : Self(Self), Prev(Self.EvalTracker) {
12374 Self.EvalTracker =
this;
12377 ~EvaluationTracker() {
12378 Self.EvalTracker = Prev;
12380 Prev->EvalOK &= EvalOK;
12383 bool evaluate(
const Expr *
E,
bool &Result) {
12387 Result, Self.SemaRef.Context,
12388 Self.SemaRef.isConstantEvaluatedContext());
12393 SequenceChecker &Self;
12394 EvaluationTracker *Prev;
12395 bool EvalOK =
true;
12396 } *EvalTracker =
nullptr;
12400 Object getObject(
const Expr *
E,
bool Mod)
const {
12403 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
12404 return getObject(UO->getSubExpr(), Mod);
12406 if (BO->getOpcode() == BO_Comma)
12407 return getObject(BO->getRHS(), Mod);
12408 if (Mod && BO->isAssignmentOp())
12409 return getObject(BO->getLHS(), Mod);
12410 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
12412 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
12413 return ME->getMemberDecl();
12414 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
12423 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
12425 Usage &
U = UI.Uses[UK];
12426 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
12430 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
12431 ModAsSideEffect->push_back(std::make_pair(O,
U));
12433 U.UsageExpr = UsageExpr;
12443 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
12444 UsageKind OtherKind,
bool IsModMod) {
12448 const Usage &
U = UI.Uses[OtherKind];
12449 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12452 const Expr *Mod =
U.UsageExpr;
12453 const Expr *ModOrUse = UsageExpr;
12454 if (OtherKind == UK_Use)
12455 std::swap(Mod, ModOrUse);
12459 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12460 : diag::warn_unsequenced_mod_use)
12462 UI.Diagnosed =
true;
12491 void notePreUse(Object O,
const Expr *UseExpr) {
12492 UsageInfo &UI = UsageMap[O];
12494 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
12497 void notePostUse(Object O,
const Expr *UseExpr) {
12498 UsageInfo &UI = UsageMap[O];
12499 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
12501 addUsage(O, UI, UseExpr, UK_Use);
12504 void notePreMod(Object O,
const Expr *ModExpr) {
12505 UsageInfo &UI = UsageMap[O];
12507 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
12508 checkUsage(O, UI, ModExpr, UK_Use,
false);
12511 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
12512 UsageInfo &UI = UsageMap[O];
12513 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
12515 addUsage(O, UI, ModExpr, UK);
12519 SequenceChecker(
Sema &S,
const Expr *
E,
12521 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12525 (void)this->WorkList;
12528 void VisitStmt(
const Stmt *S) {
12532 void VisitExpr(
const Expr *
E) {
12534 Base::VisitStmt(
E);
12538 for (
auto *Sub : CSE->
children()) {
12539 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
12554 void VisitCastExpr(
const CastExpr *
E) {
12556 if (
E->getCastKind() == CK_LValueToRValue)
12557 O = getObject(
E->getSubExpr(),
false);
12566 void VisitSequencedExpressions(
const Expr *SequencedBefore,
12567 const Expr *SequencedAfter) {
12568 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12569 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12570 SequenceTree::Seq OldRegion = Region;
12573 SequencedSubexpression SeqBefore(*
this);
12574 Region = BeforeRegion;
12575 Visit(SequencedBefore);
12578 Region = AfterRegion;
12579 Visit(SequencedAfter);
12581 Region = OldRegion;
12583 Tree.merge(BeforeRegion);
12584 Tree.merge(AfterRegion);
12592 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12599 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12600 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12606 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12613 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12614 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12619 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12631 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12635 SequenceTree::Seq RHSRegion;
12636 SequenceTree::Seq LHSRegion;
12638 RHSRegion =
Tree.allocate(Region);
12639 LHSRegion =
Tree.allocate(Region);
12641 RHSRegion = Region;
12642 LHSRegion = Region;
12644 SequenceTree::Seq OldRegion = Region;
12660 SequencedSubexpression SeqBefore(*
this);
12661 Region = RHSRegion;
12665 Region = LHSRegion;
12668 if (O && isa<CompoundAssignOperator>(BO))
12669 notePostUse(O, BO);
12673 Region = LHSRegion;
12676 if (O && isa<CompoundAssignOperator>(BO))
12677 notePostUse(O, BO);
12679 Region = RHSRegion;
12687 Region = OldRegion;
12691 : UK_ModAsSideEffect);
12693 Tree.merge(RHSRegion);
12694 Tree.merge(LHSRegion);
12699 VisitBinAssign(CAO);
12702 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12703 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12707 return VisitExpr(UO);
12715 : UK_ModAsSideEffect);
12718 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12719 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12723 return VisitExpr(UO);
12727 notePostMod(O, UO, UK_ModAsSideEffect);
12736 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12737 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12738 SequenceTree::Seq OldRegion = Region;
12740 EvaluationTracker Eval(*
this);
12742 SequencedSubexpression Sequenced(*
this);
12743 Region = LHSRegion;
12750 bool EvalResult =
false;
12751 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12752 bool ShouldVisitRHS = !EvalOK || !EvalResult;
12753 if (ShouldVisitRHS) {
12754 Region = RHSRegion;
12758 Region = OldRegion;
12759 Tree.merge(LHSRegion);
12760 Tree.merge(RHSRegion);
12769 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12770 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12771 SequenceTree::Seq OldRegion = Region;
12773 EvaluationTracker Eval(*
this);
12775 SequencedSubexpression Sequenced(*
this);
12776 Region = LHSRegion;
12782 bool EvalResult =
false;
12783 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12784 bool ShouldVisitRHS = !EvalOK || EvalResult;
12785 if (ShouldVisitRHS) {
12786 Region = RHSRegion;
12790 Region = OldRegion;
12791 Tree.merge(LHSRegion);
12792 Tree.merge(RHSRegion);
12800 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12816 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12817 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12818 SequenceTree::Seq OldRegion = Region;
12820 EvaluationTracker Eval(*
this);
12822 SequencedSubexpression Sequenced(*
this);
12823 Region = ConditionRegion;
12833 bool EvalResult =
false;
12834 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12835 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
12836 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
12837 if (ShouldVisitTrueExpr) {
12838 Region = TrueRegion;
12841 if (ShouldVisitFalseExpr) {
12842 Region = FalseRegion;
12846 Region = OldRegion;
12847 Tree.merge(ConditionRegion);
12848 Tree.merge(TrueRegion);
12849 Tree.merge(FalseRegion);
12852 void VisitCallExpr(
const CallExpr *CE) {
12864 SequencedSubexpression Sequenced(*
this);
12869 SequenceTree::Seq CalleeRegion;
12870 SequenceTree::Seq OtherRegion;
12871 if (SemaRef.getLangOpts().CPlusPlus17) {
12872 CalleeRegion = Tree.allocate(Region);
12873 OtherRegion = Tree.allocate(Region);
12875 CalleeRegion = Region;
12876 OtherRegion = Region;
12878 SequenceTree::Seq OldRegion = Region;
12881 Region = CalleeRegion;
12883 SequencedSubexpression Sequenced(*this);
12884 Visit(CE->getCallee());
12886 Visit(CE->getCallee());
12890 Region = OtherRegion;
12894 Region = OldRegion;
12896 Tree.merge(CalleeRegion);
12897 Tree.merge(OtherRegion);
12915 return VisitCallExpr(CXXOCE);
12926 case OO_MinusEqual:
12928 case OO_SlashEqual:
12929 case OO_PercentEqual:
12930 case OO_CaretEqual:
12933 case OO_LessLessEqual:
12934 case OO_GreaterGreaterEqual:
12935 SequencingKind = RHSBeforeLHS;
12939 case OO_GreaterGreater:
12945 SequencingKind = LHSBeforeRHS;
12949 SequencingKind = LHSBeforeRest;
12953 SequencingKind = NoSequencing;
12957 if (SequencingKind == NoSequencing)
12958 return VisitCallExpr(CXXOCE);
12961 SequencedSubexpression Sequenced(*
this);
12964 assert(SemaRef.getLangOpts().CPlusPlus17 &&
12965 "Should only get there with C++17 and above!");
12966 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12967 "Should only get there with an overloaded binary operator"
12968 " or an overloaded call operator!");
12970 if (SequencingKind == LHSBeforeRest) {
12971 assert(CXXOCE->getOperator() == OO_Call &&
12972 "We should only have an overloaded call operator here!");
12981 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12982 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12983 SequenceTree::Seq OldRegion = Region;
12985 assert(CXXOCE->getNumArgs() >= 1 &&
12986 "An overloaded call operator must have at least one argument"
12987 " for the postfix-expression!");
12988 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12989 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12990 CXXOCE->getNumArgs() - 1);
12994 Region = PostfixExprRegion;
12995 SequencedSubexpression Sequenced(*this);
12996 Visit(PostfixExpr);
13000 Region = ArgsRegion;
13001 for (const Expr *Arg : Args)
13004 Region = OldRegion;
13005 Tree.merge(PostfixExprRegion);
13006 Tree.merge(ArgsRegion);
13008 assert(CXXOCE->getNumArgs() == 2 &&
13009 "Should only have two arguments here!");
13010 assert((SequencingKind == LHSBeforeRHS ||
13011 SequencingKind == RHSBeforeLHS) &&
13012 "Unexpected sequencing kind!");
13016 const Expr *E1 = CXXOCE->getArg(0);
13017 const Expr *E2 = CXXOCE->getArg(1);
13018 if (SequencingKind == RHSBeforeLHS)
13021 return VisitSequencedExpressions(E1, E2);
13028 SequencedSubexpression Sequenced(*
this);
13031 return VisitExpr(CCE);
13034 SequenceExpressionsInOrder(
13040 return VisitExpr(ILE);
13043 SequenceExpressionsInOrder(ILE->
inits());
13055 SequenceTree::Seq
Parent = Region;
13056 for (
const Expr *
E : ExpressionList) {
13060 Elts.push_back(Region);
13066 for (
unsigned I = 0; I < Elts.size(); ++I)
13067 Tree.merge(Elts[I]);
13071 SequenceChecker::UsageInfo::UsageInfo() =
default;
13075 void Sema::CheckUnsequencedOperations(
const Expr *
E) {
13077 WorkList.push_back(
E);
13078 while (!WorkList.empty()) {
13079 const Expr *Item = WorkList.pop_back_val();
13080 SequenceChecker(*
this, Item, WorkList);
13085 bool IsConstexpr) {
13087 IsConstexpr || isa<ConstantExpr>(
E));
13088 CheckImplicitConversions(
E, CheckLoc);
13090 CheckUnsequencedOperations(
E);
13092 CheckForIntOverflow(
E);
13093 DiagnoseMisalignedMembers();
13106 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
13110 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
13114 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
13128 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
13132 bool CheckParameterNames) {
13133 bool HasInvalidParm =
false;
13135 assert(Param &&
"null in a parameter list");
13144 if (!Param->isInvalidDecl() &&
13145 (RequireCompleteType(Param->getLocation(), Param->getType(),
13146 diag::err_typecheck_decl_incomplete_type) ||
13147 RequireNonAbstractType(Param->getBeginLoc(), Param->getOriginalType(),
13148 diag::err_abstract_type_in_decl,
13149 AbstractParamType))) {
13150 Param->setInvalidDecl();
13151 HasInvalidParm =
true;
13156 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
13157 !Param->isImplicit() && !getLangOpts().
CPlusPlus) {
13159 if (!getLangOpts().
C23)
13160 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
13168 QualType PType = Param->getOriginalType();
13176 if (!Param->isInvalidDecl()) {
13178 if (!ClassDecl->isInvalidDecl() &&
13179 !ClassDecl->hasIrrelevantDestructor() &&
13180 !ClassDecl->isDependentContext() &&
13181 ClassDecl->isParamDestroyedInCallee()) {
13183 MarkFunctionReferenced(Param->getLocation(), Destructor);
13184 DiagnoseUseOfDecl(Destructor, Param->getLocation());
13193 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
13194 if (!Param->getType().isConstQualified())
13195 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
13199 if (LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
13204 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
13205 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
13210 if (!Param->isInvalidDecl() &&
13212 Param->setInvalidDecl();
13213 HasInvalidParm =
true;
13214 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
13218 return HasInvalidParm;
13221 std::optional<std::pair<
13230 static std::pair<CharUnits, CharUnits>
13238 if (
Base->isVirtual()) {
13245 BaseAlignment =
std::min(BaseAlignment, NonVirtualAlignment);
13252 DerivedType =
Base->getType();
13255 return std::make_pair(BaseAlignment,
Offset);
13259 static std::optional<std::pair<CharUnits, CharUnits>>
13265 return std::nullopt;
13270 return std::nullopt;
13277 return std::make_pair(
P->first,
P->second +
Offset);
13283 return std::make_pair(
13284 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
13290 std::optional<std::pair<
13298 case Stmt::CStyleCastExprClass:
13299 case Stmt::CXXStaticCastExprClass:
13300 case Stmt::ImplicitCastExprClass: {
13301 auto *CE = cast<CastExpr>(
E);
13302 const Expr *From = CE->getSubExpr();
13303 switch (CE->getCastKind()) {
13308 case CK_UncheckedDerivedToBase:
13309 case CK_DerivedToBase: {
13319 case Stmt::ArraySubscriptExprClass: {
13320 auto *ASE = cast<ArraySubscriptExpr>(
E);
13324 case Stmt::DeclRefExprClass: {
13325 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
13328 if (!VD->getType()->isReferenceType()) {
13330 if (VD->hasDependentAlignment())
13339 case Stmt::MemberExprClass: {
13340 auto *ME = cast<MemberExpr>(
E);
13341 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
13345 std::optional<std::pair<CharUnits, CharUnits>>
P;
13354 return std::make_pair(
P->first,
13357 case Stmt::UnaryOperatorClass: {
13358 auto *UO = cast<UnaryOperator>(
E);
13367 case Stmt::BinaryOperatorClass: {
13368 auto *BO = cast<BinaryOperator>(
E);
13379 return std::nullopt;
13384 std::optional<std::pair<
13393 case Stmt::CStyleCastExprClass:
13394 case Stmt::CXXStaticCastExprClass:
13395 case Stmt::ImplicitCastExprClass: {
13396 auto *CE = cast<CastExpr>(
E);
13397 const Expr *From = CE->getSubExpr();
13398 switch (CE->getCastKind()) {
13403 case CK_ArrayToPointerDecay:
13405 case CK_UncheckedDerivedToBase:
13406 case CK_DerivedToBase: {
13416 case Stmt::CXXThisExprClass: {
13421 case Stmt::UnaryOperatorClass: {
13422 auto *UO = cast<UnaryOperator>(
E);
13427 case Stmt::BinaryOperatorClass: {
13428 auto *BO = cast<BinaryOperator>(
E);
13436 if (
Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13437 std::swap(LHS, RHS);
13447 return std::nullopt;
13452 std::optional<std::pair<CharUnits, CharUnits>>
P =
13456 return P->first.alignmentAtOffset(
P->second);
13465 if (getDiagnostics().isIgnored(diag::warn_cast_align, TRange.
getBegin()))
13474 if (!DestPtr)
return;
13480 if (DestAlign.
isOne())
return;
13484 if (!SrcPtr)
return;
13495 if (SrcAlign >= DestAlign)
return;
13500 <<
static_cast<unsigned>(DestAlign.
getQuantity())
13504 void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
13506 bool AllowOnePastEnd,
bool IndexNegated) {
13508 if (isConstantEvaluatedContext())
13515 const Type *EffectiveType =
13522 StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel();
13524 const Type *BaseType =
13526 bool IsUnboundedArray =
13528 Context, StrictFlexArraysLevel,
13539 if (IndexNegated) {
13540 index.setIsUnsigned(
false);
13544 if (IsUnboundedArray) {
13547 if (index.isUnsigned() || !index.isNegative()) {
13548 const auto &ASTC = getASTContext();
13549 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
13551 if (index.getBitWidth() < AddrBits)
13552 index = index.zext(AddrBits);
13553 std::optional<CharUnits> ElemCharUnits =
13554 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13557 if (!ElemCharUnits || ElemCharUnits->isZero())
13559 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13564 if (index.getActiveBits() <= AddrBits) {
13568 Product = Product.umul_ov(ElemBytes, Overflow);
13569 if (!Overflow && Product.getActiveBits() <= AddrBits)
13575 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13576 MaxElems = MaxElems.zext(
std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13578 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13579 MaxElems = MaxElems.udiv(ElemBytes);
13582 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13583 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13587 DiagRuntimeBehavior(BaseExpr->
getBeginLoc(), BaseExpr,
13589 <<
toString(index, 10,
true) << AddrBits
13590 << (
unsigned)ASTC.toBits(*ElemCharUnits)
13593 << (
unsigned)MaxElems.getLimitedValue(~0
U)
13598 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13600 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13602 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13603 ND = ME->getMemberDecl();
13607 PDiag(diag::note_array_declared_here) << ND);
13612 if (index.isUnsigned() || !index.isNegative()) {
13624 if (BaseType != EffectiveType) {
13632 if (!ptrarith_typesize)
13635 if (ptrarith_typesize != array_typesize) {
13637 uint64_t ratio = array_typesize / ptrarith_typesize;
13641 if (ptrarith_typesize * ratio == array_typesize)
13646 if (size.getBitWidth() > index.getBitWidth())
13647 index = index.zext(size.getBitWidth());
13648 else if (size.getBitWidth() < index.getBitWidth())
13649 size = size.zext(index.getBitWidth());
13655 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
13664 if (SourceMgr.isInSystemHeader(RBracketLoc)) {
13666 SourceMgr.getSpellingLoc(IndexExpr->
getBeginLoc());
13667 if (SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
13672 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
13673 : diag::warn_ptr_arith_exceeds_bounds;
13674 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13677 DiagRuntimeBehavior(
13682 unsigned DiagID = diag::warn_array_index_precedes_bounds;
13684 DiagID = diag::warn_ptr_arith_precedes_bounds;
13685 if (index.isNegative()) index = -index;
13688 DiagRuntimeBehavior(BaseExpr->
getBeginLoc(), BaseExpr,
13689 PDiag(DiagID) <<
toString(index, 10,
true)
13695 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13697 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13699 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13700 ND = ME->getMemberDecl();
13704 PDiag(diag::note_array_declared_here) << ND);
13707 void Sema::CheckArrayAccess(
const Expr *
expr) {
13708 int AllowOnePastEnd = 0;
13710 expr =
expr->IgnoreParenImpCasts();
13711 switch (
expr->getStmtClass()) {
13712 case Stmt::ArraySubscriptExprClass: {
13715 AllowOnePastEnd > 0);
13719 case Stmt::MemberExprClass: {
13720 expr = cast<MemberExpr>(
expr)->getBase();
13723 case Stmt::ArraySectionExprClass: {
13729 nullptr, AllowOnePastEnd > 0);
13732 case Stmt::UnaryOperatorClass: {
13748 case Stmt::ConditionalOperatorClass: {
13751 CheckArrayAccess(lhs);
13753 CheckArrayAccess(rhs);
13756 case Stmt::CXXOperatorCallExprClass: {
13757 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
13758 for (
const auto *Arg : OCE->arguments())
13759 CheckArrayAccess(Arg);
13769 Expr *RHS,
bool isProperty) {
13781 S.
Diag(
Loc, diag::warn_arc_literal_assign)
13783 << (isProperty ? 0 : 1)
13791 Expr *RHS,
bool isProperty) {
13794 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13795 S.
Diag(
Loc, diag::warn_arc_retained_assign)
13797 << (isProperty ? 0 : 1)
13801 RHS =
cast->getSubExpr();
13843 if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
Loc))
13844 getCurFunction()->markSafeWeakUse(LHS);
13847 if (checkUnsafeAssigns(
Loc, LHSType, RHS))
13872 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13873 Diag(
Loc, diag::warn_arc_retained_property_assign)
13877 RHS =
cast->getSubExpr();
13900 bool StmtLineInvalid;
13903 if (StmtLineInvalid)
13906 bool BodyLineInvalid;
13909 if (BodyLineInvalid)
13913 if (StmtLine != BodyLine)
13924 if (CurrentInstantiationScope)
13928 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13937 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13941 const Stmt *PossibleBody) {
13942 assert(!CurrentInstantiationScope);
13947 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
13948 StmtLoc = FS->getRParenLoc();
13949 Body = FS->getBody();
13950 DiagID = diag::warn_empty_for_body;
13951 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
13952 StmtLoc = WS->getRParenLoc();
13953 Body = WS->getBody();
13954 DiagID = diag::warn_empty_while_body;
13959 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13964 if (Diags.isIgnored(DiagID, NBody->
getSemiLoc()))
13982 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
13983 if (!ProbableTypo) {
13984 bool BodyColInvalid;
13985 unsigned BodyCol = SourceMgr.getPresumedColumnNumber(
13987 if (BodyColInvalid)
13990 bool StmtColInvalid;
13992 SourceMgr.getPresumedColumnNumber(S->getBeginLoc(), &StmtColInvalid);
13993 if (StmtColInvalid)
13996 if (BodyCol > StmtCol)
13997 ProbableTypo =
true;
14000 if (ProbableTypo) {
14002 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
14010 if (Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
14013 if (inTemplateInstantiation())
14022 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
14024 RHSExpr = CE->
getArg(0);
14025 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
14026 CXXSCE && CXXSCE->isXValue())
14027 RHSExpr = CXXSCE->getSubExpr();
14031 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
14032 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
14035 if (LHSDeclRef && RHSDeclRef) {
14042 auto D =
Diag(OpLoc, diag::warn_self_move)
14046 getSelfAssignmentClassMemberCandidate(RHSDeclRef->
getDecl()))
14058 const Expr *LHSBase = LHSExpr;
14059 const Expr *RHSBase = RHSExpr;
14060 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
14061 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
14062 if (!LHSME || !RHSME)
14065 while (LHSME && RHSME) {
14072 LHSME = dyn_cast<MemberExpr>(LHSBase);
14073 RHSME = dyn_cast<MemberExpr>(RHSBase);
14076 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
14077 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
14078 if (LHSDeclRef && RHSDeclRef) {
14085 Diag(OpLoc, diag::warn_self_move)
14091 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
14092 Diag(OpLoc, diag::warn_self_move)
14116 bool AreUnionMembers =
false) {
14117 [[maybe_unused]]
const Type *Field1Parent =
14119 [[maybe_unused]]
const Type *Field2Parent =
14124 "Can't evaluate layout compatibility between a struct field and a "
14127 (AreUnionMembers && Field1Parent->
isUnionType())) &&
14128 "AreUnionMembers should be 'true' for union fields (only).");
14141 if (Bits1 != Bits2)
14145 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
14146 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
14149 if (!AreUnionMembers &&
14161 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
14162 RD1 = D1CXX->getStandardLayoutBaseWithFields();
14164 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
14165 RD2 = D2CXX->getStandardLayoutBaseWithFields();
14170 return isLayoutCompatible(C, F1, F2);
14179 for (
auto *Field2 : RD2->
fields())
14180 UnmatchedFields.insert(Field2);
14182 for (
auto *Field1 : RD1->
fields()) {
14183 auto I = UnmatchedFields.begin();
14184 auto E = UnmatchedFields.end();
14186 for ( ; I !=
E; ++I) {
14188 bool Result = UnmatchedFields.erase(*I);
14198 return UnmatchedFields.empty();
14224 if (C.hasSameType(T1, T2))
14233 if (TC1 == Type::Enum) {
14235 cast<EnumType>(T1)->getDecl(),
14236 cast<EnumType>(T2)->getDecl());
14242 cast<RecordType>(T1)->getDecl(),
14243 cast<RecordType>(T2)->getDecl());
14257 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
14261 getASTContext().hasSameType(BaseT, DerivedT))
14289 bool isConstantEvaluated) {
14297 case Stmt::UnaryOperatorClass: {
14306 case Stmt::DeclRefExprClass: {
14307 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
14312 case Stmt::IntegerLiteralClass: {
14315 if (MagicValueAPInt.getActiveBits() <= 64) {
14316 *MagicValue = MagicValueAPInt.getZExtValue();
14322 case Stmt::BinaryConditionalOperatorClass:
14323 case Stmt::ConditionalOperatorClass: {
14325 cast<AbstractConditionalOperator>(TypeExpr);
14328 isConstantEvaluated)) {
14338 case Stmt::BinaryOperatorClass: {
14341 TypeExpr = BO->
getRHS();
14371 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
14374 bool isConstantEvaluated) {
14375 FoundWrongKind =
false;
14382 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
14386 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
14387 if (I->getArgumentKind() != ArgumentKind) {
14388 FoundWrongKind =
true;
14391 TypeInfo.Type = I->getMatchingCType();
14392 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
14393 TypeInfo.MustBeNull = I->getMustBeNull();
14404 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
14405 if (I == MagicValues->end())
14414 bool LayoutCompatible,
14416 if (!TypeTagForDatatypeMagicValues)
14417 TypeTagForDatatypeMagicValues.reset(
14418 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14421 (*TypeTagForDatatypeMagicValues)[Magic] =
14437 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14438 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14439 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14440 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14443 void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
14447 bool IsPointerAttr =
Attr->getIsPointer();
14450 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14451 if (TypeTagIdxAST >= ExprArgs.size()) {
14452 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14453 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14456 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
14457 bool FoundWrongKind;
14460 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14461 TypeInfo, isConstantEvaluatedContext())) {
14462 if (FoundWrongKind)
14464 diag::warn_type_tag_for_datatype_wrong_kind)
14470 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14471 if (ArgumentIdxAST >= ExprArgs.size()) {
14472 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14473 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
14476 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
14477 if (IsPointerAttr) {
14479 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14480 if (ICE->getType()->isVoidPointerType() &&
14481 ICE->getCastKind() == CK_BitCast)
14482 ArgumentExpr = ICE->getSubExpr();
14495 diag::warn_type_safety_null_pointer_required)
14507 bool mismatch =
false;
14509 mismatch = !Context.
hasSameType(ArgumentType, RequiredType);
14530 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14531 << ArgumentType << ArgumentKind
14532 <<
TypeInfo.LayoutCompatible << RequiredType
14539 MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14543 for (MisalignedMember &m : MisalignedMembers) {
14549 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14552 MisalignedMembers.clear();
14559 if (isa<UnaryOperator>(
E) &&
14560 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14561 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14562 if (isa<MemberExpr>(Op)) {
14563 auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14564 if (MA != MisalignedMembers.end() &&
14569 MisalignedMembers.erase(MA);
14578 const auto *ME = dyn_cast<MemberExpr>(
E);
14590 bool AnyIsPacked =
false;
14592 QualType BaseType = ME->getBase()->getType();
14602 auto *FD = dyn_cast<FieldDecl>(MD);
14608 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14609 ReverseMemberChain.push_back(FD);
14612 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14614 assert(TopME &&
"We did not compute a topmost MemberExpr!");
14621 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
14625 if (!DRE && !isa<CXXThisExpr>(TopBase))
14632 if (ExpectedAlignment.
isOne())
14637 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
14642 ReverseMemberChain.back()->getParent()->getTypeForDecl());
14646 if (DRE && !TopME->
isArrow()) {
14649 CompleteObjectAlignment =
14654 if (
Offset % ExpectedAlignment != 0 ||
14657 CompleteObjectAlignment < ExpectedAlignment) {
14668 for (
FieldDecl *FDI : ReverseMemberChain) {
14669 if (FDI->hasAttr<PackedAttr>() ||
14670 FDI->getParent()->hasAttr<PackedAttr>()) {
14678 assert(FD &&
"We did not find a packed FieldDecl!");
14683 void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
14684 using namespace std::placeholders;
14686 RefersToMemberWithReducedAlignment(
14687 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14692 if (checkArgCount(TheCall, 1))
14709 bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall) {
14711 if (BuiltinVectorMath(TheCall, Res))
14719 if (BuiltinVectorMath(TheCall, Res))
14723 TheCall->
setType(VecTy0->getElementType());
14731 if (checkArgCount(TheCall, 2))
14738 Res = UsualArithmeticConversions(A, B, TheCall->
getExprLoc(), ACK_Comparison);
14747 diag::err_typecheck_call_different_arg_types)
14759 bool CheckForFloatArgs) {
14760 if (checkArgCount(TheCall, 3))
14764 for (
int I = 0; I < 3; ++I) {
14768 Args[I] = Converted.
get();
14771 if (CheckForFloatArgs) {
14772 int ArgOrdinal = 1;
14773 for (
Expr *Arg : Args) {
14775 Arg->
getType(), ArgOrdinal++))
14779 int ArgOrdinal = 1;
14780 for (
Expr *Arg : Args) {
14787 for (
int I = 1; I < 3; ++I) {
14788 if (Args[0]->getType().getCanonicalType() !=
14789 Args[I]->getType().getCanonicalType()) {
14790 return Diag(Args[0]->getBeginLoc(),
14791 diag::err_typecheck_call_different_arg_types)
14795 TheCall->
setArg(I, Args[I]);
14798 TheCall->
setType(Args[0]->getType());
14802 bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
14803 if (checkArgCount(TheCall, 1))
14814 bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
14815 if (checkArgCount(TheCall, 1))
14823 << 1 << 0 << TyArg;
14831 if (checkArgCount(TheCall, 1))
14837 Expr *Matrix = MatrixArg.
get();
14842 << 1 << 1 << Matrix->
getType();
14849 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14852 TheCall->
setType(ResultType);
14855 TheCall->
setArg(0, Matrix);
14860 static std::optional<unsigned>
14863 std::optional<llvm::APSInt>
Value =
14881 if (!getLangOpts().MatrixTypes) {
14886 if (checkArgCount(TheCall, 4))
14889 unsigned PtrArgIdx = 0;
14895 bool ArgError =
false;
14899 ExprResult PtrConv = DefaultFunctionArrayLvalueConversion(PtrExpr);
14902 PtrExpr = PtrConv.
get();
14903 TheCall->
setArg(0, PtrExpr);
14914 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14921 << PtrArgIdx + 1 << 2
14928 auto ApplyArgumentConversions = [
this](
Expr *
E) {
14937 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
14939 RowsExpr = RowsConv.
get();
14940 TheCall->
setArg(1, RowsExpr);
14942 RowsExpr =
nullptr;
14944 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14946 ColumnsExpr = ColumnsConv.
get();
14947 TheCall->
setArg(2, ColumnsExpr);
14949 ColumnsExpr =
nullptr;
14960 std::optional<unsigned> MaybeRows;
14964 std::optional<unsigned> MaybeColumns;
14969 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
14972 StrideExpr = StrideConv.
get();
14973 TheCall->
setArg(3, StrideExpr);
14976 if (std::optional<llvm::APSInt>
Value =
14979 if (Stride < *MaybeRows) {
14981 diag::err_builtin_matrix_stride_too_small);
14987 if (ArgError || !MaybeRows || !MaybeColumns)
14997 if (checkArgCount(TheCall, 3))
15000 unsigned PtrArgIdx = 1;
15005 bool ArgError =
false;
15008 ExprResult MatrixConv = DefaultLvalueConversion(MatrixExpr);
15011 MatrixExpr = MatrixConv.
get();
15012 TheCall->
setArg(0, MatrixExpr);
15022 << 1 << 1 << MatrixExpr->
getType();
15027 ExprResult PtrConv = DefaultFunctionArrayLvalueConversion(PtrExpr);
15030 PtrExpr = PtrConv.
get();
15031 TheCall->
setArg(1, PtrExpr);
15042 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
15047 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
15052 !Context.
hasSameType(ElementTy, MatrixTy->getElementType())) {
15054 diag::err_builtin_matrix_pointer_arg_mismatch)
15055 << ElementTy << MatrixTy->getElementType();
15063 ExprResult StrideConv = DefaultLvalueConversion(StrideExpr);
15067 StrideConv = tryConvertExprToType(StrideConv.
get(), Context.
getSizeType());
15070 StrideExpr = StrideConv.
get();
15071 TheCall->
setArg(2, StrideExpr);
15076 if (std::optional<llvm::APSInt>
Value =
15079 if (Stride < MatrixTy->getNumRows()) {
15081 diag::err_builtin_matrix_stride_too_small);
15096 if (isUnevaluatedContext())
15099 const NamedDecl *Caller = getCurFunctionOrMethodDecl();
15101 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
15106 llvm::StringSet<> CalleeTCBs;
15107 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
15108 CalleeTCBs.insert(A->getTCBName());
15109 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
15110 CalleeTCBs.insert(A->getTCBName());
15114 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
15115 StringRef CallerTCB = A->getTCBName();
15116 if (CalleeTCBs.count(CallerTCB) == 0) {
15117 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
15118 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
llvm::MachO::Record Record
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Pseudo-evaluate the given integer expression, estimating the range of values it might take.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, bool inFunctionCall, Sema::VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, Sema::VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
static IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth)
static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool)
static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool pruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static QualType GetExprType(const Expr *E)
static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, SourceLocation CC)
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool isKnownToHaveUnsignedValue(Expr *E)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static llvm::APSInt getSYCLAllocaDefaultSize(const ASTContext &Ctx, const VarDecl *VD)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static bool checkIntelFPGARegArgument(Sema &S, QualType ArgType, SourceLocation &Loc)
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool IsSameCharType(QualType T1, QualType T2)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static int classifyConstantValue(Expr *Constant)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static bool requiresParensToAddCast(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool IsEnumConstOrFromMacro(Sema &S, Expr *E)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static const Expr * getStrlenExprArg(const Expr *E)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static bool HasEnumType(Expr *E)
static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SYCL constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the TargetCXXABI class, which abstracts details of the C++ ABI that we're targeting.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
const NestedNameSpecifier * Specifier
__DEVICE__ int min(int __a, int __b)
__DEVICE__ int max(int __a, int __b)
__device__ __2f16 float __ockl_bool s
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
unsigned getStructNumFields() const
bool isComplexInt() const
ValueKind getKind() const
APSInt & getComplexIntReal()
bool isComplexFloat() const
unsigned getVectorLength() const
APSInt & getComplexIntImag()
APValue & getStructField(unsigned i)
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getVectorElt(unsigned I)
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible SVE vector types, false otherwise.
const clang::PrintingPolicy & getPrintingPolicy() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
bool areCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an RISC-V vector builtin type and a VectorType that is a fixed-len...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const ConstantArrayType * getAsConstantArrayType(QualType T) const
bool areLaxCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible RISC-V vector types as defined by -flax-vect...
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
const LangOptions & getLangOpts() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
llvm::APFixedPoint getFixedPointMin(QualType Ty) const
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
TypeInfoChars getTypeInfoInChars(const Type *T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getExceptionObjectType(QualType T) const
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const
Return the type for the specified builtin.
CanQualType UnsignedShortTy
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
llvm::APFixedPoint getFixedPointMax(QualType Ty) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
bool areCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an SVE builtin and a VectorType that is a fixed-length representat...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
CanQualType getNSIntegerType() const
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
const TargetInfo * getAuxTargetInfo() const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
QualType getTypedefType(const TypedefNameDecl *Decl, QualType Underlying=QualType()) const
Return the unique reference to the type for the specified typedef-name decl.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
CanQualType getNSUIntegerType() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
std::unique_ptr< AtomicScopeModel > getScopeModel() const
Get atomic scope model.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ConceptDecl * getTypeConstraintConcept() const
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getExprLoc() const
bool isEqualityOp() const
static bool isAdditiveOp(Opcode Opc)
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
llvm::StringRef getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
bool isTSBuiltin(unsigned ID) const
Return true if this function is a target-specific builtin.
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
ArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
bool isDynamicClass() const
CXXRecordDecl * getDefinition() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr ** getArgs()
Retrieve the call arguments.
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isCallToStdMove() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
SourceLocation getRParenLoc() const
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
Declaration of a C++20 concept.
ConditionalOperator - The ?: ternary operator.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
Represents a concrete matrix type with constant number of rows and columns.
static constexpr unsigned getMaxElementsPerDimension()
Returns the maximum number of elements per dimension.
static constexpr bool isDimensionValid(size_t NumElements)
Returns true if NumElements is a valid matrix dimension.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents an expression that might suspend coroutine execution; either a co_await or co_yield expres...
Expr * getOperand() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const LLVM_READONLY
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
SourceLocation getLocation() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isComplete() const
Returns true if this can be considered a complete type.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
unsigned getNumPositiveBits() const
Returns the width in bits required to store all the non-negative enumerators of this enum.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isFlexibleArrayMemberLike(ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue(const ASTContext &Ctx) const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to call this function.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
ArrayRef< ParmVarDecl * > parameters() const
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
const ParmVarDecl * getParamDecl(unsigned i) const
Represents a prototype with parameter type info, e.g.
ArrayRef< QualType > getParamTypes() const
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
FunctionType - C99 6.7.5.3 - Function Declarators.
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isValidElementType(QualType T)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isCXX98PODType(const ASTContext &Context) const
Return true if this is a POD type according to the rules of the C++98 standard, regardless of the cur...
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
bool isSignedCharBool(QualType Ty)
void adornBoolConversionDiagWithTernaryFixit(Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
@ KernelCallVariadicFunction
static bool isSyclType(QualType Ty, SYCLTypeAttr::SYCLType TypeName)
Check whether Ty corresponds to a SYCL type of name TypeName.
Sema - This implements semantic analysis and AST building for C.
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
bool FormatStringHasSArg(const StringLiteral *FExpr)
static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI)
Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo parameter with the Format...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
static FormatStringType GetFormatStringType(const FormatAttr *Format)
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
Scope * getCurScope() const
Retrieve the parser's current scope.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool IsLayoutCompatible(QualType T1, QualType T2) const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
const LangOptions & getLangOpts() const
static const uint64_t MaximumAlignment
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall)
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
void pushCodeSynthesisContext(CodeSynthesisContext Ctx)
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res)
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
SourceManager & getSourceManager() const
bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, bool CheckForFloatArgs=true)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
bool isConstantEvaluatedContext() const
ASTContext & getASTContext() const
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
SourceManager & SourceMgr
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
DiagnosticsEngine & getDiagnostics() const
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
Exposes information about the current target.
virtual bool validatePointerAuthKey(const llvm::APSInt &value) const
Determine whether the given pointer-authentication key is valid.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
virtual bool supportsCpuInit() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
const llvm::fltSemantics & getLongDoubleFormat() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool checkArithmeticFenceSupported() const
Controls if __arithmetic_fence is supported in the targeted backend.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
virtual bool hasSjLjLowering() const
Controls if __builtin_longjmp / __builtin_setjmp can be lowered to llvm.eh.sjlj.longjmp / llvm....
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Represents a template argument.
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
@ Type
The template argument is a type.
ArgKind getKind() const
Return the kind of stored template argument.
const Type * getTypeForDecl() const
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isFloat16Type() const
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
The iterator over UnresolvedSets.
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
Represents a GCC generic vector type.
unsigned getNumElements() const
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
ComparisonResult
Indicates the result of a tentative comparison.
uint32_t Literal
Literals are represented as positive integers.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ After
Like System, but searched after the system directories.
@ FixIt
Parse and apply any fixits to the source.
bool GT(InterpState &S, CodePtr OpPC)
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool InRange(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
std::string toString(const til::SExpr *E)
The JSON file list parser is used to communicate input to InstallAPI.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ NonNull
Values of this type can never be null.
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
LangAS
Defines the address space values used by the address space qualifier of QualType.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
CastKind
CastKind - The kind of operation required for a conversion.
ActionResult< ParsedType > TypeResult
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
const FunctionProtoType * T
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Other
Other implicit parameter.
float __ovld __cnfn distance(float, float)
Returns the distance between p0 and p1.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
Describes how types, statements, expressions, and declarations should be printed.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
A context in which code is being synthesized (where a source location alone is not sufficient to iden...
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.