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/STLForwardCompat.h"
89#include "llvm/ADT/SmallBitVector.h"
90#include "llvm/ADT/SmallPtrSet.h"
91#include "llvm/ADT/SmallString.h"
92#include "llvm/ADT/SmallVector.h"
93#include "llvm/ADT/StringExtras.h"
94#include "llvm/ADT/StringRef.h"
95#include "llvm/ADT/StringSet.h"
96#include "llvm/ADT/StringSwitch.h"
97#include "llvm/Support/AtomicOrdering.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"
120using namespace clang;
124 unsigned ByteNo)
const {
135 unsigned ArgCount =
Call->getNumArgs();
136 if (ArgCount >= MinArgCount)
139 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
140 << 0 << MinArgCount << ArgCount
141 << 0 <<
Call->getSourceRange();
145 unsigned ArgCount =
Call->getNumArgs();
146 if (ArgCount <= MaxArgCount)
148 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
149 << 0 << MaxArgCount << ArgCount
150 << 0 <<
Call->getSourceRange();
154 unsigned MaxArgCount) {
160 unsigned ArgCount =
Call->getNumArgs();
161 if (ArgCount == DesiredArgCount)
166 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
170 Call->getArg(ArgCount - 1)->getEndLoc());
172 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
173 << 0 << DesiredArgCount << ArgCount
178 bool HasError =
false;
180 for (
const Expr *Arg :
Call->arguments()) {
181 if (Arg->isValueDependent())
184 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
185 int DiagMsgKind = -1;
187 if (!ArgString.has_value())
189 else if (ArgString->find(
'$') != std::string::npos)
192 if (DiagMsgKind >= 0) {
193 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
194 << DiagMsgKind << Arg->getSourceRange();
203 if (
Value->isTypeDependent())
210 if (Result.isInvalid())
212 Value = Result.get();
234 if (!Literal || !Literal->isOrdinary()) {
247 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
255 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
256 if (!Literal || !Literal->isWide()) {
257 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
258 << Arg->getSourceRange();
295 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
326 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
328 auto IsValidIntegerType = [](
QualType Ty) {
329 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
336 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
340 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
346 if (!IsValidIntegerType(AlignOp->
getType())) {
357 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
358 llvm::APSInt MaxValue(
359 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
360 if (AlignValue < 1) {
361 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
364 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
369 if (!AlignValue.isPowerOf2()) {
370 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
373 if (AlignValue == 1) {
374 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
375 << IsBooleanAlignBuiltin;
403 std::pair<unsigned, const char *> Builtins[] = {
404 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
405 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
406 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
409 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
416 auto ValidCkdIntType = [](
QualType QT) {
419 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
420 return (BT->getKind() >= BuiltinType::Short &&
421 BT->getKind() <= BuiltinType::Int128) || (
422 BT->getKind() >= BuiltinType::UShort &&
423 BT->getKind() <= BuiltinType::UInt128) ||
424 BT->getKind() == BuiltinType::UChar ||
425 BT->getKind() == BuiltinType::SChar;
430 for (
unsigned I = 0; I < 2; ++I) {
436 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
455 !PtrTy->getPointeeType()->isIntegerType() ||
456 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
457 PtrTy->getPointeeType().isConstQualified()) {
459 diag::err_overflow_builtin_must_be_ptr_int)
467 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
468 for (
unsigned I = 0; I < 3; ++I) {
469 const auto Arg = TheCall->
getArg(I);
472 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
474 return S.
Diag(Arg->getBeginLoc(),
475 diag::err_overflow_builtin_bit_int_max_size)
484struct BuiltinDumpStructGenerator {
488 SmallVector<Expr *, 32> Actions;
489 DiagnosticErrorTrap ErrorTracker;
490 PrintingPolicy Policy;
492 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
493 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
494 Policy(S.Context.getPrintingPolicy()) {
498 Expr *makeOpaqueValueExpr(Expr *Inner) {
502 Actions.push_back(OVE);
506 Expr *getStringLiteral(llvm::StringRef Str) {
509 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
512 bool callPrintFunction(llvm::StringRef Format,
513 llvm::ArrayRef<Expr *> Exprs = {}) {
514 SmallVector<Expr *, 8> Args;
516 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
518 Args.push_back(getStringLiteral(Format));
519 llvm::append_range(Args, Exprs);
522 Sema::CodeSynthesisContext Ctx;
535 Actions.push_back(RealCall.
get());
541 Expr *getIndentString(
unsigned Depth) {
545 llvm::SmallString<32>
Indent;
547 return getStringLiteral(
Indent);
551 return getStringLiteral(
T.getAsString(Policy));
554 bool appendFormatSpecifier(QualType
T, llvm::SmallVectorImpl<char> &Str) {
555 llvm::raw_svector_ostream
OS(Str);
559 if (
auto *BT =
T->
getAs<BuiltinType>()) {
560 switch (BT->getKind()) {
561 case BuiltinType::Bool:
564 case BuiltinType::Char_U:
565 case BuiltinType::UChar:
568 case BuiltinType::Char_S:
569 case BuiltinType::SChar:
577 analyze_printf::PrintfSpecifier
Specifier;
580 if (
Specifier.getConversionSpecifier().getKind() ==
581 analyze_printf::PrintfConversionSpecifier::sArg) {
587 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
607 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
608 Expr *IndentLit = getIndentString(Depth);
610 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
611 : callPrintFunction(
"%s", {TypeLit}))
614 return dumpRecordValue(RD, E, IndentLit, Depth);
618 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
627 Expr *RecordArg = makeOpaqueValueExpr(E);
630 if (callPrintFunction(
" {\n"))
634 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
635 for (
const auto &Base : CXXRD->bases()) {
643 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
649 Expr *FieldIndentArg = getIndentString(Depth + 1);
652 for (
auto *D : RD->
decls()) {
653 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
654 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
655 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
658 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
659 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
661 getStringLiteral(FD->getName())};
663 if (FD->isBitField()) {
667 FD->getBitWidthValue());
675 CXXScopeSpec(), Loc, IFD,
678 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
680 DeclarationNameInfo(FD->getDeclName(), Loc));
681 if (
Field.isInvalid())
684 auto *InnerRD = FD->getType()->getAsRecordDecl();
685 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
686 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
688 if (callPrintFunction(Format, Args) ||
689 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
693 if (appendFormatSpecifier(FD->getType(), Format)) {
695 Args.push_back(
Field.get());
705 Args.push_back(FieldAddr.
get());
708 if (callPrintFunction(Format, Args))
713 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
714 : callPrintFunction(
"}\n");
717 Expr *buildWrapper() {
720 TheCall->
setType(Wrapper->getType());
741 diag::err_expected_struct_pointer_argument)
750 diag::err_incomplete_type))
759 switch (BT ? BT->getKind() : BuiltinType::Void) {
760 case BuiltinType::Dependent:
761 case BuiltinType::Overload:
762 case BuiltinType::BoundMember:
763 case BuiltinType::PseudoObject:
764 case BuiltinType::UnknownAny:
765 case BuiltinType::BuiltinFn:
771 diag::err_expected_callable_argument)
777 BuiltinDumpStructGenerator Generator(S, TheCall);
783 Expr *PtrArg = PtrArgResult.
get();
787 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
790 return Generator.buildWrapper();
802 if (
Call->getStmtClass() != Stmt::CallExprClass) {
803 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
804 <<
Call->getSourceRange();
809 if (CE->getCallee()->getType()->isBlockPointerType()) {
810 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
811 <<
Call->getSourceRange();
815 const Decl *TargetDecl = CE->getCalleeDecl();
816 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
817 if (FD->getBuiltinID()) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
819 <<
Call->getSourceRange();
824 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
825 <<
Call->getSourceRange();
833 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
847 BuiltinCall->
setType(CE->getType());
851 BuiltinCall->
setArg(1, ChainResult.
get());
858class ScanfDiagnosticFormatHandler
862 using ComputeSizeFunction =
863 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
867 using DiagnoseFunction =
868 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
870 ComputeSizeFunction ComputeSizeArgument;
871 DiagnoseFunction Diagnose;
874 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
875 DiagnoseFunction Diagnose)
876 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
878 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
879 const char *StartSpecifier,
880 unsigned specifierLen)
override {
884 unsigned NulByte = 0;
896 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
898 analyze_format_string::OptionalAmount::HowSpecified::Constant)
903 std::optional<llvm::APSInt> DestSizeAPS =
908 unsigned DestSize = DestSizeAPS->getZExtValue();
910 if (DestSize < SourceSize)
917class EstimateSizeFormatHandler
922 bool IsKernelCompatible =
true;
925 EstimateSizeFormatHandler(StringRef Format)
926 :
Size(std::
min(Format.find(0), Format.size()) +
929 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
930 const char *,
unsigned SpecifierLen,
931 const TargetInfo &)
override {
933 const size_t FieldWidth = computeFieldWidth(FS);
934 const size_t Precision = computePrecision(FS);
941 Size += std::max(FieldWidth, (
size_t)1);
953 Size += std::max(FieldWidth, Precision);
969 Size += std::max(FieldWidth, 1 +
970 (Precision ? 1 + Precision
980 (Precision ? 1 + Precision : 0) +
990 (Precision ? 1 + Precision : 0) +
1005 IsKernelCompatible =
false;
1006 Size += std::max(FieldWidth, 2 + Precision);
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; }
1069 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1070 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1071 size_t FieldWidth = 0;
1077 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1078 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1079 size_t Precision = 0;
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();
1132 Context.getAsConstantArrayType(Format->getType());
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));
1142void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1148 bool UseDABAttr =
false;
1149 const FunctionDecl *UseDecl = FD;
1151 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1153 UseDecl = DABAttr->getFunction();
1154 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
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;
1189 Expr *SizeArg = TheCall->
getArg(NewIndex);
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 std::string FunctionNameStr =
1250 llvm::StringRef FunctionName = FunctionNameStr;
1255 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1256 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1258 FunctionName.consume_front(
"__builtin_");
1260 return FunctionName.str();
1263 switch (BuiltinID) {
1266 case Builtin::BI__builtin_stpcpy:
1267 case Builtin::BIstpcpy:
1268 case Builtin::BI__builtin_strcpy:
1269 case Builtin::BIstrcpy: {
1270 DiagID = diag::warn_fortify_strlen_overflow;
1271 SourceSize = ComputeStrLenArgument(1);
1272 DestinationSize = ComputeSizeArgument(0);
1276 case Builtin::BI__builtin___stpcpy_chk:
1277 case Builtin::BI__builtin___strcpy_chk: {
1278 DiagID = diag::warn_fortify_strlen_overflow;
1279 SourceSize = ComputeStrLenArgument(1);
1280 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1281 IsChkVariant =
true;
1285 case Builtin::BIscanf:
1286 case Builtin::BIfscanf:
1287 case Builtin::BIsscanf: {
1288 unsigned FormatIndex = 1;
1289 unsigned DataIndex = 2;
1290 if (BuiltinID == Builtin::BIscanf) {
1295 const auto *FormatExpr =
1298 StringRef FormatStrRef;
1303 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1304 unsigned SourceSize) {
1305 DiagID = diag::warn_fortify_scanf_overflow;
1306 unsigned Index = ArgIndex + DataIndex;
1307 std::string FunctionName = GetFunctionName();
1309 PDiag(DiagID) << FunctionName << (Index + 1)
1310 << DestSize << SourceSize);
1313 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1314 return ComputeSizeArgument(Index + DataIndex);
1316 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1317 const char *FormatBytes = FormatStrRef.data();
1328 case Builtin::BIsprintf:
1329 case Builtin::BI__builtin___sprintf_chk: {
1330 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1333 StringRef FormatStrRef;
1336 EstimateSizeFormatHandler H(FormatStrRef);
1337 const char *FormatBytes = FormatStrRef.data();
1339 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1340 Context.getTargetInfo(),
false)) {
1341 DiagID = H.isKernelCompatible()
1342 ? diag::warn_format_overflow
1343 : diag::warn_format_overflow_non_kprintf;
1344 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1345 .extOrTrunc(SizeTypeWidth);
1346 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1347 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1348 IsChkVariant =
true;
1350 DestinationSize = ComputeSizeArgument(0);
1357 case Builtin::BI__builtin___memcpy_chk:
1358 case Builtin::BI__builtin___memmove_chk:
1359 case Builtin::BI__builtin___memset_chk:
1360 case Builtin::BI__builtin___strlcat_chk:
1361 case Builtin::BI__builtin___strlcpy_chk:
1362 case Builtin::BI__builtin___strncat_chk:
1363 case Builtin::BI__builtin___strncpy_chk:
1364 case Builtin::BI__builtin___stpncpy_chk:
1365 case Builtin::BI__builtin___memccpy_chk:
1366 case Builtin::BI__builtin___mempcpy_chk: {
1367 DiagID = diag::warn_builtin_chk_overflow;
1368 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1370 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1371 IsChkVariant =
true;
1375 case Builtin::BI__builtin___snprintf_chk:
1376 case Builtin::BI__builtin___vsnprintf_chk: {
1377 DiagID = diag::warn_builtin_chk_overflow;
1378 SourceSize = ComputeExplicitObjectSizeArgument(1);
1379 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1380 IsChkVariant =
true;
1384 case Builtin::BIstrncat:
1385 case Builtin::BI__builtin_strncat:
1386 case Builtin::BIstrncpy:
1387 case Builtin::BI__builtin_strncpy:
1388 case Builtin::BIstpncpy:
1389 case Builtin::BI__builtin_stpncpy: {
1395 DiagID = diag::warn_fortify_source_size_mismatch;
1396 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1397 DestinationSize = ComputeSizeArgument(0);
1401 case Builtin::BImemcpy:
1402 case Builtin::BI__builtin_memcpy:
1403 case Builtin::BImemmove:
1404 case Builtin::BI__builtin_memmove:
1405 case Builtin::BImemset:
1406 case Builtin::BI__builtin_memset:
1407 case Builtin::BImempcpy:
1408 case Builtin::BI__builtin_mempcpy: {
1409 DiagID = diag::warn_fortify_source_overflow;
1410 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1411 DestinationSize = ComputeSizeArgument(0);
1414 case Builtin::BIsnprintf:
1415 case Builtin::BI__builtin_snprintf:
1416 case Builtin::BIvsnprintf:
1417 case Builtin::BI__builtin_vsnprintf: {
1418 DiagID = diag::warn_fortify_source_size_mismatch;
1419 SourceSize = ComputeExplicitObjectSizeArgument(1);
1421 StringRef FormatStrRef;
1425 EstimateSizeFormatHandler H(FormatStrRef);
1426 const char *FormatBytes = FormatStrRef.data();
1428 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1429 Context.getTargetInfo(),
false)) {
1430 llvm::APSInt FormatSize =
1431 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1432 .extOrTrunc(SizeTypeWidth);
1433 if (FormatSize > *SourceSize && *SourceSize != 0) {
1434 unsigned TruncationDiagID =
1435 H.isKernelCompatible() ? diag::warn_format_truncation
1436 : diag::warn_format_truncation_non_kprintf;
1437 SmallString<16> SpecifiedSizeStr;
1438 SmallString<16> FormatSizeStr;
1439 SourceSize->toString(SpecifiedSizeStr, 10);
1440 FormatSize.toString(FormatSizeStr, 10);
1442 PDiag(TruncationDiagID)
1443 << GetFunctionName() << SpecifiedSizeStr
1448 DestinationSize = ComputeSizeArgument(0);
1452 if (!SourceSize || !DestinationSize ||
1453 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1456 std::string FunctionName = GetFunctionName();
1458 SmallString<16> DestinationStr;
1459 SmallString<16> SourceStr;
1460 DestinationSize->toString(DestinationStr, 10);
1461 SourceSize->toString(SourceStr, 10);
1464 << FunctionName << DestinationStr << SourceStr);
1479 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1482 << DRE->getDecl()->getIdentifier();
1494 "__builtin_alloca has invalid address space");
1507 if (Arg->isTypeDependent() || Arg->isValueDependent())
1510 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1512 return S.
Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1520enum PointerAuthOpKind {
1535 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1566 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1569 llvm::raw_svector_ostream Str(
Value);
1578 Result = KeyValue->getZExtValue();
1597 bool IsAddrDiscArg =
false;
1602 IsAddrDiscArg =
true;
1611 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1612 <<
Result->getExtValue();
1614 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1620 IntVal =
Result->getZExtValue();
1624static std::pair<const ValueDecl *, CharUnits>
1631 const auto *BaseDecl =
1636 return {BaseDecl, Result.Val.getLValueOffset()};
1640 bool RequireConstant =
false) {
1648 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1649 return OpKind != PAO_BlendInteger;
1651 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1652 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1653 OpKind == PAO_SignGeneric;
1662 }
else if (AllowsInteger(OpKind) &&
1669 <<
unsigned(OpKind == PAO_Discriminator ? 1
1670 : OpKind == PAO_BlendPointer ? 2
1671 : OpKind == PAO_BlendInteger ? 3
1673 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1683 if (!RequireConstant) {
1685 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1688 ? diag::warn_ptrauth_sign_null_pointer
1689 : diag::warn_ptrauth_auth_null_pointer)
1699 if (OpKind == PAO_Sign) {
1717 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1722 assert(OpKind == PAO_Discriminator);
1728 if (
Call->getBuiltinCallee() ==
1729 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1744 assert(
Pointer->getType()->isPointerType());
1756 assert(
Integer->getType()->isIntegerType());
1762 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1775 Call->setType(
Call->getArgs()[0]->getType());
1806 PointerAuthOpKind OpKind,
1807 bool RequireConstant) {
1818 Call->setType(
Call->getArgs()[0]->getType());
1834 Call->setType(
Call->getArgs()[0]->getType());
1843 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1846 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1847 if (!Literal || Literal->getCharByteWidth() != 1) {
1863 Call->setArg(0, FirstValue.
get());
1869 if (!FirstArgRecord) {
1870 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1871 << 0 << FirstArgType;
1876 diag::err_get_vtable_pointer_requires_complete_type)) {
1881 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1882 << 1 << FirstArgRecord;
1886 Call->setType(ReturnType);
1911 auto DiagSelect = [&]() -> std::optional<unsigned> {
1918 return std::optional<unsigned>{};
1933 diag::err_incomplete_type))
1937 "Unhandled non-object pointer case");
1965 if (PT->getPointeeType()->isFunctionType()) {
1967 diag::err_builtin_is_within_lifetime_invalid_arg)
1973 if (PT->getPointeeType()->isVariableArrayType()) {
1975 << 1 <<
"__builtin_is_within_lifetime";
1980 diag::err_builtin_is_within_lifetime_invalid_arg)
1994 diag::err_builtin_trivially_relocate_invalid_arg_type)
2001 diag::err_incomplete_type))
2005 T->isIncompleteArrayType()) {
2007 diag::err_builtin_trivially_relocate_invalid_arg_type)
2008 << (
T.isConstQualified() ? 1 : 2);
2017 diag::err_builtin_trivially_relocate_invalid_arg_type)
2024 if (Size.isInvalid())
2028 if (Size.isInvalid())
2030 SizeExpr = Size.get();
2031 TheCall->
setArg(2, SizeExpr);
2041 llvm::Triple::ObjectFormatType CurObjFormat =
2043 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2056 llvm::Triple::ArchType CurArch =
2058 if (llvm::is_contained(SupportedArchs, CurArch))
2068bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2075 case llvm::Triple::arm:
2076 case llvm::Triple::armeb:
2077 case llvm::Triple::thumb:
2078 case llvm::Triple::thumbeb:
2080 case llvm::Triple::aarch64:
2081 case llvm::Triple::aarch64_32:
2082 case llvm::Triple::aarch64_be:
2084 case llvm::Triple::bpfeb:
2085 case llvm::Triple::bpfel:
2087 case llvm::Triple::dxil:
2089 case llvm::Triple::hexagon:
2091 case llvm::Triple::mips:
2092 case llvm::Triple::mipsel:
2093 case llvm::Triple::mips64:
2094 case llvm::Triple::mips64el:
2096 case llvm::Triple::spirv:
2097 case llvm::Triple::spirv32:
2098 case llvm::Triple::spirv64:
2099 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2102 case llvm::Triple::systemz:
2104 case llvm::Triple::x86:
2105 case llvm::Triple::x86_64:
2107 case llvm::Triple::ppc:
2108 case llvm::Triple::ppcle:
2109 case llvm::Triple::ppc64:
2110 case llvm::Triple::ppc64le:
2112 case llvm::Triple::amdgcn:
2114 case llvm::Triple::riscv32:
2115 case llvm::Triple::riscv64:
2117 case llvm::Triple::loongarch32:
2118 case llvm::Triple::loongarch64:
2121 case llvm::Triple::wasm32:
2122 case llvm::Triple::wasm64:
2124 case llvm::Triple::nvptx:
2125 case llvm::Triple::nvptx64:
2139 EltTy = VecTy->getElementType();
2141 switch (ArgTyRestr) {
2145 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2146 << ArgOrdinal << 2 << 1 << 1
2152 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2153 << ArgOrdinal << 5 << 0
2159 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2160 << ArgOrdinal << 5 << 1
2166 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2180 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2181 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2182 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2183 "Expecting __builtin_cpu_...");
2185 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2187 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2188 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2189 (!IsCPUSupports && TInfo->supportsCpuIs()));
2191 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2198 ? diag::err_builtin_aix_os_unsupported
2199 : diag::err_builtin_target_unsupported)
2205 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2257 TheCall->
setArg(0, Arg0);
2274 TheCall->
setArg(1, Arg1);
2280 << 2 << 1 << 4 << 0 << Arg1Ty;
2289 unsigned Pos,
bool AllowConst,
2293 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2298 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2299 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2300 << Pos <<
"scalar pointer";
2309 diag::err_typecheck_convert_incompatible)
2318 bool TypeDependent =
false;
2319 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2347 Builtin::BI__builtin_masked_load))
2361 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2384 Builtin::BI__builtin_masked_store))
2392 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2402 diag::err_vec_builtin_incompatible_vector)
2431 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2444 << MaskTy << IdxTy);
2453 diag::err_vec_masked_load_store_ptr)
2482 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2498 << MaskTy << IdxTy);
2504 << MaskTy << ValTy);
2510 diag::err_vec_builtin_incompatible_vector)
2524 if (Args.size() == 0) {
2526 diag::err_typecheck_call_too_few_args_at_least)
2532 QualType FuncT = Args[0]->getType();
2535 if (Args.size() < 2) {
2537 diag::err_typecheck_call_too_few_args_at_least)
2543 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2544 QualType ObjectT = Args[1]->getType();
2546 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2595 tok::periodstar, ObjectArg.
get(), Args[0]);
2599 if (MPT->isMemberDataPointer())
2602 auto *MemCall =
new (S.
Context)
2625Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2630 unsigned ICEArguments = 0;
2632 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2637 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2639 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2644 if (ArgNo < TheCall->getNumArgs() &&
2647 ICEArguments &= ~(1 << ArgNo);
2651 switch (BuiltinID) {
2652 case Builtin::BI__builtin_cpu_supports:
2653 case Builtin::BI__builtin_cpu_is:
2655 Context.getAuxTargetInfo(), BuiltinID))
2658 case Builtin::BI__builtin_cpu_init:
2659 if (!
Context.getTargetInfo().supportsCpuInit()) {
2665 case Builtin::BI__builtin___CFStringMakeConstantString:
2669 *
this, BuiltinID, TheCall,
2670 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2673 "Wrong # arguments to builtin CFStringMakeConstantString");
2674 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2677 case Builtin::BI__builtin_ms_va_start:
2678 case Builtin::BI__builtin_stdarg_start:
2679 case Builtin::BI__builtin_va_start:
2680 case Builtin::BI__builtin_c23_va_start:
2681 if (BuiltinVAStart(BuiltinID, TheCall))
2684 case Builtin::BI__va_start: {
2685 switch (
Context.getTargetInfo().getTriple().getArch()) {
2686 case llvm::Triple::aarch64:
2687 case llvm::Triple::arm:
2688 case llvm::Triple::thumb:
2689 if (BuiltinVAStartARMMicrosoft(TheCall))
2693 if (BuiltinVAStart(BuiltinID, TheCall))
2701 case Builtin::BI_interlockedbittestandset_acq:
2702 case Builtin::BI_interlockedbittestandset_rel:
2703 case Builtin::BI_interlockedbittestandset_nf:
2704 case Builtin::BI_interlockedbittestandreset_acq:
2705 case Builtin::BI_interlockedbittestandreset_rel:
2706 case Builtin::BI_interlockedbittestandreset_nf:
2709 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2714 case Builtin::BI_bittest64:
2715 case Builtin::BI_bittestandcomplement64:
2716 case Builtin::BI_bittestandreset64:
2717 case Builtin::BI_bittestandset64:
2718 case Builtin::BI_interlockedbittestandreset64:
2719 case Builtin::BI_interlockedbittestandset64:
2722 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2723 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2728 case Builtin::BI_interlockedbittestandreset64_acq:
2729 case Builtin::BI_interlockedbittestandreset64_rel:
2730 case Builtin::BI_interlockedbittestandreset64_nf:
2731 case Builtin::BI_interlockedbittestandset64_acq:
2732 case Builtin::BI_interlockedbittestandset64_rel:
2733 case Builtin::BI_interlockedbittestandset64_nf:
2738 case Builtin::BI__builtin_set_flt_rounds:
2741 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2742 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2743 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2744 llvm::Triple::ppc64le}))
2748 case Builtin::BI__builtin_isgreater:
2749 case Builtin::BI__builtin_isgreaterequal:
2750 case Builtin::BI__builtin_isless:
2751 case Builtin::BI__builtin_islessequal:
2752 case Builtin::BI__builtin_islessgreater:
2753 case Builtin::BI__builtin_isunordered:
2754 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2757 case Builtin::BI__builtin_fpclassify:
2758 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2761 case Builtin::BI__builtin_isfpclass:
2762 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2765 case Builtin::BI__builtin_isfinite:
2766 case Builtin::BI__builtin_isinf:
2767 case Builtin::BI__builtin_isinf_sign:
2768 case Builtin::BI__builtin_isnan:
2769 case Builtin::BI__builtin_issignaling:
2770 case Builtin::BI__builtin_isnormal:
2771 case Builtin::BI__builtin_issubnormal:
2772 case Builtin::BI__builtin_iszero:
2773 case Builtin::BI__builtin_signbit:
2774 case Builtin::BI__builtin_signbitf:
2775 case Builtin::BI__builtin_signbitl:
2776 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2779 case Builtin::BI__builtin_shufflevector:
2783 case Builtin::BI__builtin_masked_load:
2784 case Builtin::BI__builtin_masked_expand_load:
2786 case Builtin::BI__builtin_masked_store:
2787 case Builtin::BI__builtin_masked_compress_store:
2789 case Builtin::BI__builtin_masked_gather:
2791 case Builtin::BI__builtin_masked_scatter:
2793 case Builtin::BI__builtin_invoke:
2795 case Builtin::BI__builtin_prefetch:
2796 if (BuiltinPrefetch(TheCall))
2799 case Builtin::BI__builtin_alloca_with_align:
2800 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2801 if (BuiltinAllocaWithAlign(TheCall))
2804 case Builtin::BI__builtin_alloca:
2805 case Builtin::BI__builtin_alloca_uninitialized:
2812 case Builtin::BI__builtin_infer_alloc_token:
2816 case Builtin::BI__arithmetic_fence:
2817 if (BuiltinArithmeticFence(TheCall))
2820 case Builtin::BI__assume:
2821 case Builtin::BI__builtin_assume:
2822 if (BuiltinAssume(TheCall))
2825 case Builtin::BI__builtin_assume_aligned:
2826 if (BuiltinAssumeAligned(TheCall))
2829 case Builtin::BI__builtin_dynamic_object_size:
2830 case Builtin::BI__builtin_object_size:
2834 case Builtin::BI__builtin_longjmp:
2835 if (BuiltinLongjmp(TheCall))
2838 case Builtin::BI__builtin_setjmp:
2839 if (BuiltinSetjmp(TheCall))
2842 case Builtin::BI__builtin_classify_type:
2847 case Builtin::BI__builtin_complex:
2848 if (BuiltinComplex(TheCall))
2851 case Builtin::BI__builtin_constant_p: {
2860 case Builtin::BI__builtin_launder:
2862 case Builtin::BI__builtin_is_within_lifetime:
2864 case Builtin::BI__builtin_trivially_relocate:
2867 case Builtin::BI__sync_fetch_and_add:
2868 case Builtin::BI__sync_fetch_and_add_1:
2869 case Builtin::BI__sync_fetch_and_add_2:
2870 case Builtin::BI__sync_fetch_and_add_4:
2871 case Builtin::BI__sync_fetch_and_add_8:
2872 case Builtin::BI__sync_fetch_and_add_16:
2873 case Builtin::BI__sync_fetch_and_sub:
2874 case Builtin::BI__sync_fetch_and_sub_1:
2875 case Builtin::BI__sync_fetch_and_sub_2:
2876 case Builtin::BI__sync_fetch_and_sub_4:
2877 case Builtin::BI__sync_fetch_and_sub_8:
2878 case Builtin::BI__sync_fetch_and_sub_16:
2879 case Builtin::BI__sync_fetch_and_or:
2880 case Builtin::BI__sync_fetch_and_or_1:
2881 case Builtin::BI__sync_fetch_and_or_2:
2882 case Builtin::BI__sync_fetch_and_or_4:
2883 case Builtin::BI__sync_fetch_and_or_8:
2884 case Builtin::BI__sync_fetch_and_or_16:
2885 case Builtin::BI__sync_fetch_and_and:
2886 case Builtin::BI__sync_fetch_and_and_1:
2887 case Builtin::BI__sync_fetch_and_and_2:
2888 case Builtin::BI__sync_fetch_and_and_4:
2889 case Builtin::BI__sync_fetch_and_and_8:
2890 case Builtin::BI__sync_fetch_and_and_16:
2891 case Builtin::BI__sync_fetch_and_xor:
2892 case Builtin::BI__sync_fetch_and_xor_1:
2893 case Builtin::BI__sync_fetch_and_xor_2:
2894 case Builtin::BI__sync_fetch_and_xor_4:
2895 case Builtin::BI__sync_fetch_and_xor_8:
2896 case Builtin::BI__sync_fetch_and_xor_16:
2897 case Builtin::BI__sync_fetch_and_nand:
2898 case Builtin::BI__sync_fetch_and_nand_1:
2899 case Builtin::BI__sync_fetch_and_nand_2:
2900 case Builtin::BI__sync_fetch_and_nand_4:
2901 case Builtin::BI__sync_fetch_and_nand_8:
2902 case Builtin::BI__sync_fetch_and_nand_16:
2903 case Builtin::BI__sync_add_and_fetch:
2904 case Builtin::BI__sync_add_and_fetch_1:
2905 case Builtin::BI__sync_add_and_fetch_2:
2906 case Builtin::BI__sync_add_and_fetch_4:
2907 case Builtin::BI__sync_add_and_fetch_8:
2908 case Builtin::BI__sync_add_and_fetch_16:
2909 case Builtin::BI__sync_sub_and_fetch:
2910 case Builtin::BI__sync_sub_and_fetch_1:
2911 case Builtin::BI__sync_sub_and_fetch_2:
2912 case Builtin::BI__sync_sub_and_fetch_4:
2913 case Builtin::BI__sync_sub_and_fetch_8:
2914 case Builtin::BI__sync_sub_and_fetch_16:
2915 case Builtin::BI__sync_and_and_fetch:
2916 case Builtin::BI__sync_and_and_fetch_1:
2917 case Builtin::BI__sync_and_and_fetch_2:
2918 case Builtin::BI__sync_and_and_fetch_4:
2919 case Builtin::BI__sync_and_and_fetch_8:
2920 case Builtin::BI__sync_and_and_fetch_16:
2921 case Builtin::BI__sync_or_and_fetch:
2922 case Builtin::BI__sync_or_and_fetch_1:
2923 case Builtin::BI__sync_or_and_fetch_2:
2924 case Builtin::BI__sync_or_and_fetch_4:
2925 case Builtin::BI__sync_or_and_fetch_8:
2926 case Builtin::BI__sync_or_and_fetch_16:
2927 case Builtin::BI__sync_xor_and_fetch:
2928 case Builtin::BI__sync_xor_and_fetch_1:
2929 case Builtin::BI__sync_xor_and_fetch_2:
2930 case Builtin::BI__sync_xor_and_fetch_4:
2931 case Builtin::BI__sync_xor_and_fetch_8:
2932 case Builtin::BI__sync_xor_and_fetch_16:
2933 case Builtin::BI__sync_nand_and_fetch:
2934 case Builtin::BI__sync_nand_and_fetch_1:
2935 case Builtin::BI__sync_nand_and_fetch_2:
2936 case Builtin::BI__sync_nand_and_fetch_4:
2937 case Builtin::BI__sync_nand_and_fetch_8:
2938 case Builtin::BI__sync_nand_and_fetch_16:
2939 case Builtin::BI__sync_val_compare_and_swap:
2940 case Builtin::BI__sync_val_compare_and_swap_1:
2941 case Builtin::BI__sync_val_compare_and_swap_2:
2942 case Builtin::BI__sync_val_compare_and_swap_4:
2943 case Builtin::BI__sync_val_compare_and_swap_8:
2944 case Builtin::BI__sync_val_compare_and_swap_16:
2945 case Builtin::BI__sync_bool_compare_and_swap:
2946 case Builtin::BI__sync_bool_compare_and_swap_1:
2947 case Builtin::BI__sync_bool_compare_and_swap_2:
2948 case Builtin::BI__sync_bool_compare_and_swap_4:
2949 case Builtin::BI__sync_bool_compare_and_swap_8:
2950 case Builtin::BI__sync_bool_compare_and_swap_16:
2951 case Builtin::BI__sync_lock_test_and_set:
2952 case Builtin::BI__sync_lock_test_and_set_1:
2953 case Builtin::BI__sync_lock_test_and_set_2:
2954 case Builtin::BI__sync_lock_test_and_set_4:
2955 case Builtin::BI__sync_lock_test_and_set_8:
2956 case Builtin::BI__sync_lock_test_and_set_16:
2957 case Builtin::BI__sync_lock_release:
2958 case Builtin::BI__sync_lock_release_1:
2959 case Builtin::BI__sync_lock_release_2:
2960 case Builtin::BI__sync_lock_release_4:
2961 case Builtin::BI__sync_lock_release_8:
2962 case Builtin::BI__sync_lock_release_16:
2963 case Builtin::BI__sync_swap:
2964 case Builtin::BI__sync_swap_1:
2965 case Builtin::BI__sync_swap_2:
2966 case Builtin::BI__sync_swap_4:
2967 case Builtin::BI__sync_swap_8:
2968 case Builtin::BI__sync_swap_16:
2969 return BuiltinAtomicOverloaded(TheCallResult);
2970 case Builtin::BI__sync_synchronize:
2974 case Builtin::BI__builtin_nontemporal_load:
2975 case Builtin::BI__builtin_nontemporal_store:
2976 return BuiltinNontemporalOverloaded(TheCallResult);
2977 case Builtin::BI__builtin_memcpy_inline: {
2978 clang::Expr *SizeOp = TheCall->
getArg(2);
2990 case Builtin::BI__builtin_memset_inline: {
2991 clang::Expr *SizeOp = TheCall->
getArg(2);
3001#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3002 case Builtin::BI##ID: \
3003 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3004#include "clang/Basic/Builtins.inc"
3005 case Builtin::BI__annotation:
3009 case Builtin::BI__builtin_annotation:
3013 case Builtin::BI__builtin_addressof:
3017 case Builtin::BI__builtin_function_start:
3021 case Builtin::BI__builtin_is_aligned:
3022 case Builtin::BI__builtin_align_up:
3023 case Builtin::BI__builtin_align_down:
3027 case Builtin::BI__builtin_add_overflow:
3028 case Builtin::BI__builtin_sub_overflow:
3029 case Builtin::BI__builtin_mul_overflow:
3033 case Builtin::BI__builtin_operator_new:
3034 case Builtin::BI__builtin_operator_delete: {
3035 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3037 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3040 case Builtin::BI__builtin_dump_struct:
3042 case Builtin::BI__builtin_expect_with_probability: {
3047 const Expr *ProbArg = TheCall->
getArg(2);
3048 SmallVector<PartialDiagnosticAt, 8> Notes;
3049 Expr::EvalResult Eval;
3053 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3060 bool LoseInfo =
false;
3061 Probability.convert(llvm::APFloat::IEEEdouble(),
3062 llvm::RoundingMode::Dynamic, &LoseInfo);
3063 if (!(Probability >= llvm::APFloat(0.0) &&
3064 Probability <= llvm::APFloat(1.0))) {
3071 case Builtin::BI__builtin_preserve_access_index:
3075 case Builtin::BI__builtin_call_with_static_chain:
3079 case Builtin::BI__exception_code:
3080 case Builtin::BI_exception_code:
3082 diag::err_seh___except_block))
3085 case Builtin::BI__exception_info:
3086 case Builtin::BI_exception_info:
3088 diag::err_seh___except_filter))
3091 case Builtin::BI__GetExceptionInfo:
3103 case Builtin::BIaddressof:
3104 case Builtin::BI__addressof:
3105 case Builtin::BIforward:
3106 case Builtin::BIforward_like:
3107 case Builtin::BImove:
3108 case Builtin::BImove_if_noexcept:
3109 case Builtin::BIas_const: {
3117 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3118 BuiltinID == Builtin::BI__addressof;
3120 (ReturnsPointer ?
Result->isAnyPointerType()
3121 :
Result->isReferenceType()) &&
3124 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3130 case Builtin::BI__builtin_ptrauth_strip:
3132 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3134 case Builtin::BI__builtin_ptrauth_sign_constant:
3137 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3140 case Builtin::BI__builtin_ptrauth_auth:
3143 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3145 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3147 case Builtin::BI__builtin_ptrauth_string_discriminator:
3150 case Builtin::BI__builtin_get_vtable_pointer:
3154 case Builtin::BIread_pipe:
3155 case Builtin::BIwrite_pipe:
3158 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3161 case Builtin::BIreserve_read_pipe:
3162 case Builtin::BIreserve_write_pipe:
3163 case Builtin::BIwork_group_reserve_read_pipe:
3164 case Builtin::BIwork_group_reserve_write_pipe:
3165 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3168 case Builtin::BIsub_group_reserve_read_pipe:
3169 case Builtin::BIsub_group_reserve_write_pipe:
3170 if (
OpenCL().checkSubgroupExt(TheCall) ||
3171 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3174 case Builtin::BIcommit_read_pipe:
3175 case Builtin::BIcommit_write_pipe:
3176 case Builtin::BIwork_group_commit_read_pipe:
3177 case Builtin::BIwork_group_commit_write_pipe:
3178 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3181 case Builtin::BIsub_group_commit_read_pipe:
3182 case Builtin::BIsub_group_commit_write_pipe:
3183 if (
OpenCL().checkSubgroupExt(TheCall) ||
3184 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3187 case Builtin::BIget_pipe_num_packets:
3188 case Builtin::BIget_pipe_max_packets:
3189 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3192 case Builtin::BIto_global:
3193 case Builtin::BIto_local:
3194 case Builtin::BIto_private:
3195 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3199 case Builtin::BIenqueue_kernel:
3200 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3203 case Builtin::BIget_kernel_work_group_size:
3204 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3205 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3208 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3209 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3210 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3213 case Builtin::BI__builtin_os_log_format:
3214 Cleanup.setExprNeedsCleanups(
true);
3216 case Builtin::BI__builtin_os_log_format_buffer_size:
3217 if (BuiltinOSLogFormat(TheCall))
3220 case Builtin::BI__builtin_frame_address:
3221 case Builtin::BI__builtin_return_address: {
3230 Result.Val.getInt() != 0)
3232 << ((BuiltinID == Builtin::BI__builtin_return_address)
3233 ?
"__builtin_return_address"
3234 :
"__builtin_frame_address")
3239 case Builtin::BI__builtin_nondeterministic_value: {
3240 if (BuiltinNonDeterministicValue(TheCall))
3247 case Builtin::BI__builtin_elementwise_abs:
3255 case Builtin::BI__builtin_elementwise_acos:
3256 case Builtin::BI__builtin_elementwise_asin:
3257 case Builtin::BI__builtin_elementwise_atan:
3258 case Builtin::BI__builtin_elementwise_ceil:
3259 case Builtin::BI__builtin_elementwise_cos:
3260 case Builtin::BI__builtin_elementwise_cosh:
3261 case Builtin::BI__builtin_elementwise_exp:
3262 case Builtin::BI__builtin_elementwise_exp2:
3263 case Builtin::BI__builtin_elementwise_exp10:
3264 case Builtin::BI__builtin_elementwise_floor:
3265 case Builtin::BI__builtin_elementwise_log:
3266 case Builtin::BI__builtin_elementwise_log2:
3267 case Builtin::BI__builtin_elementwise_log10:
3268 case Builtin::BI__builtin_elementwise_roundeven:
3269 case Builtin::BI__builtin_elementwise_round:
3270 case Builtin::BI__builtin_elementwise_rint:
3271 case Builtin::BI__builtin_elementwise_nearbyint:
3272 case Builtin::BI__builtin_elementwise_sin:
3273 case Builtin::BI__builtin_elementwise_sinh:
3274 case Builtin::BI__builtin_elementwise_sqrt:
3275 case Builtin::BI__builtin_elementwise_tan:
3276 case Builtin::BI__builtin_elementwise_tanh:
3277 case Builtin::BI__builtin_elementwise_trunc:
3278 case Builtin::BI__builtin_elementwise_canonicalize:
3283 case Builtin::BI__builtin_elementwise_fma:
3288 case Builtin::BI__builtin_elementwise_ldexp: {
3310 const auto *Vec0 = TyA->
getAs<VectorType>();
3311 const auto *Vec1 = TyExp->
getAs<VectorType>();
3312 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3314 if (Arg0Length != Arg1Length) {
3316 diag::err_typecheck_vector_lengths_not_equal)
3330 case Builtin::BI__builtin_elementwise_minnum:
3331 case Builtin::BI__builtin_elementwise_maxnum:
3332 case Builtin::BI__builtin_elementwise_minimum:
3333 case Builtin::BI__builtin_elementwise_maximum:
3334 case Builtin::BI__builtin_elementwise_minimumnum:
3335 case Builtin::BI__builtin_elementwise_maximumnum:
3336 case Builtin::BI__builtin_elementwise_atan2:
3337 case Builtin::BI__builtin_elementwise_fmod:
3338 case Builtin::BI__builtin_elementwise_pow:
3339 if (BuiltinElementwiseMath(TheCall,
3345 case Builtin::BI__builtin_elementwise_add_sat:
3346 case Builtin::BI__builtin_elementwise_sub_sat:
3347 if (BuiltinElementwiseMath(TheCall,
3351 case Builtin::BI__builtin_elementwise_fshl:
3352 case Builtin::BI__builtin_elementwise_fshr:
3357 case Builtin::BI__builtin_elementwise_min:
3358 case Builtin::BI__builtin_elementwise_max:
3359 if (BuiltinElementwiseMath(TheCall))
3362 case Builtin::BI__builtin_elementwise_popcount:
3363 case Builtin::BI__builtin_elementwise_bitreverse:
3368 case Builtin::BI__builtin_elementwise_copysign: {
3377 QualType MagnitudeTy = Magnitude.
get()->
getType();
3390 diag::err_typecheck_call_different_arg_types)
3391 << MagnitudeTy << SignTy;
3399 case Builtin::BI__builtin_elementwise_clzg:
3400 case Builtin::BI__builtin_elementwise_ctzg:
3408 }
else if (BuiltinElementwiseMath(
3412 case Builtin::BI__builtin_reduce_max:
3413 case Builtin::BI__builtin_reduce_min: {
3414 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3417 const Expr *Arg = TheCall->
getArg(0);
3422 ElTy = TyA->getElementType();
3426 if (ElTy.isNull()) {
3436 case Builtin::BI__builtin_reduce_maximum:
3437 case Builtin::BI__builtin_reduce_minimum: {
3438 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3441 const Expr *Arg = TheCall->
getArg(0);
3446 ElTy = TyA->getElementType();
3450 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3463 case Builtin::BI__builtin_reduce_add:
3464 case Builtin::BI__builtin_reduce_mul:
3465 case Builtin::BI__builtin_reduce_xor:
3466 case Builtin::BI__builtin_reduce_or:
3467 case Builtin::BI__builtin_reduce_and: {
3468 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3471 const Expr *Arg = TheCall->
getArg(0);
3476 ElTy = TyA->getElementType();
3480 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3491 case Builtin::BI__builtin_matrix_transpose:
3492 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3494 case Builtin::BI__builtin_matrix_column_major_load:
3495 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3497 case Builtin::BI__builtin_matrix_column_major_store:
3498 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3500 case Builtin::BI__builtin_verbose_trap:
3505 case Builtin::BI__builtin_get_device_side_mangled_name: {
3506 auto Check = [](CallExpr *TheCall) {
3512 auto *D = DRE->getDecl();
3515 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3516 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3518 if (!Check(TheCall)) {
3520 diag::err_hip_invalid_args_builtin_mangled_name);
3525 case Builtin::BI__builtin_popcountg:
3529 case Builtin::BI__builtin_clzg:
3530 case Builtin::BI__builtin_ctzg:
3535 case Builtin::BI__builtin_allow_runtime_check: {
3536 Expr *Arg = TheCall->
getArg(0);
3545 case Builtin::BI__builtin_counted_by_ref:
3546 if (BuiltinCountedByRef(TheCall))
3556 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3557 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3558 assert(
Context.getAuxTargetInfo() &&
3559 "Aux Target Builtin, but not an aux target?");
3561 if (CheckTSBuiltinFunctionCall(
3563 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3566 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3572 return TheCallResult;
3587 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3591 diag::err_argument_not_contiguous_bit_field)
3598 bool IsVariadic =
false;
3601 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3602 IsVariadic = BD->isVariadic();
3603 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3604 IsVariadic = OMD->isVariadic();
3611 bool HasImplicitThisParam,
bool IsVariadic,
3615 else if (IsVariadic)
3625 if (HasImplicitThisParam) {
3657 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3658 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3659 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3660 Expr = ILE->getInit(0);
3670 const Expr *ArgExpr,
3674 S.
PDiag(diag::warn_null_arg)
3680 if (
auto nullability =
type->getNullability())
3691 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3697 llvm::SmallBitVector NonNullArgs;
3703 for (
const auto *Arg : Args)
3710 unsigned IdxAST = Idx.getASTIndex();
3711 if (IdxAST >= Args.size())
3713 if (NonNullArgs.empty())
3714 NonNullArgs.resize(Args.size());
3715 NonNullArgs.set(IdxAST);
3724 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3729 unsigned ParamIndex = 0;
3731 I != E; ++I, ++ParamIndex) {
3734 if (NonNullArgs.empty())
3735 NonNullArgs.resize(Args.size());
3737 NonNullArgs.set(ParamIndex);
3744 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3749 type = blockType->getPointeeType();
3763 if (NonNullArgs.empty())
3764 NonNullArgs.resize(Args.size());
3766 NonNullArgs.set(Index);
3775 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3776 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3777 if (NonNullArgs[ArgIndex])
3783 StringRef ParamName,
QualType ArgTy,
3806 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3807 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3811 if (ArgAlign < ParamAlign)
3812 Diag(Loc, diag::warn_param_mismatched_alignment)
3814 << ParamName << (FDecl !=
nullptr) << FDecl;
3818 const Expr *ThisArg,
3820 if (!FD || Args.empty())
3822 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3823 if (Idx == LifetimeCaptureByAttr::Global ||
3824 Idx == LifetimeCaptureByAttr::Unknown)
3826 if (IsMemberFunction && Idx == 0)
3828 return Args[Idx - IsMemberFunction];
3830 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3835 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3836 for (
int CapturingParamIdx :
Attr->params()) {
3839 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3842 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3850 I + IsMemberFunction);
3852 if (IsMemberFunction) {
3860 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3873 llvm::SmallBitVector CheckedVarArgs;
3875 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3877 CheckedVarArgs.resize(Args.size());
3878 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
3883 CheckedVarArgs.resize(Args.size());
3884 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
3891 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3895 : isa_and_nonnull<FunctionDecl>(FDecl)
3897 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3901 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3903 if (
const Expr *Arg = Args[ArgIdx]) {
3904 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3911 if (FDecl || Proto) {
3916 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3917 CheckArgumentWithTypeTag(I, Args, Loc);
3923 if (!Proto && FDecl) {
3925 if (isa_and_nonnull<FunctionProtoType>(FT))
3931 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3933 bool IsScalableArg =
false;
3934 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3936 if (
const Expr *Arg = Args[ArgIdx]) {
3940 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
3948 IsScalableArg =
true;
3950 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3959 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3960 llvm::StringMap<bool> CallerFeatureMap;
3961 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
3962 if (!CallerFeatureMap.contains(
"sme"))
3963 Diag(Loc, diag::err_sme_call_in_non_sme_target);
3964 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
3965 Diag(Loc, diag::err_sme_call_in_non_sme_target);
3974 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3976 (IsScalableArg || IsScalableRet)) {
3977 bool IsCalleeStreaming =
3979 bool IsCalleeStreamingCompatible =
3983 if (!IsCalleeStreamingCompatible &&
3987 unsigned VL = LO.VScaleMin * 128;
3988 unsigned SVL = LO.VScaleStreamingMin * 128;
3989 bool IsVLMismatch = VL && SVL && VL != SVL;
3991 auto EmitDiag = [&](
bool IsArg) {
3995 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
3996 << IsArg << IsCalleeStreaming << SVL << VL;
3999 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4000 << IsArg << SVL << VL;
4002 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4019 bool CallerHasZAState =
false;
4020 bool CallerHasZT0State =
false;
4022 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4024 CallerHasZAState =
true;
4026 CallerHasZT0State =
true;
4030 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4032 CallerHasZT0State |=
4034 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4040 Diag(Loc, diag::err_sme_za_call_no_za_state);
4043 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4047 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4048 Diag(Loc, diag::note_sme_use_preserves_za);
4053 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4054 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4055 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4056 if (!Arg->isValueDependent()) {
4058 if (Arg->EvaluateAsInt(Align,
Context)) {
4059 const llvm::APSInt &I = Align.
Val.
getInt();
4060 if (!I.isPowerOf2())
4061 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4062 << Arg->getSourceRange();
4065 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4091 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4092 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4094 checkCall(FDecl, Proto,
nullptr, Args,
true,
4103 IsMemberOperatorCall;
4109 Expr *ImplicitThis =
nullptr;
4114 ImplicitThis = Args[0];
4117 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4128 ThisType =
Context.getPointerType(ThisType);
4134 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4152 CheckAbsoluteValueFunction(TheCall, FDecl);
4153 CheckMaxUnsignedZero(TheCall, FDecl);
4154 CheckInfNaNFunction(TheCall, FDecl);
4165 case Builtin::BIstrlcpy:
4166 case Builtin::BIstrlcat:
4167 CheckStrlcpycatArguments(TheCall, FnInfo);
4169 case Builtin::BIstrncat:
4170 CheckStrncatArguments(TheCall, FnInfo);
4172 case Builtin::BIfree:
4173 CheckFreeArguments(TheCall);
4176 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4185 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4186 Ty =
V->getType().getNonReferenceType();
4187 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4188 Ty = F->getType().getNonReferenceType();
4225 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4228 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4230 case AtomicExpr::AO__c11_atomic_init:
4231 case AtomicExpr::AO__opencl_atomic_init:
4232 llvm_unreachable(
"There is no ordering argument for an init");
4234 case AtomicExpr::AO__c11_atomic_load:
4235 case AtomicExpr::AO__opencl_atomic_load:
4236 case AtomicExpr::AO__hip_atomic_load:
4237 case AtomicExpr::AO__atomic_load_n:
4238 case AtomicExpr::AO__atomic_load:
4239 case AtomicExpr::AO__scoped_atomic_load_n:
4240 case AtomicExpr::AO__scoped_atomic_load:
4241 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4242 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4244 case AtomicExpr::AO__c11_atomic_store:
4245 case AtomicExpr::AO__opencl_atomic_store:
4246 case AtomicExpr::AO__hip_atomic_store:
4247 case AtomicExpr::AO__atomic_store:
4248 case AtomicExpr::AO__atomic_store_n:
4249 case AtomicExpr::AO__scoped_atomic_store:
4250 case AtomicExpr::AO__scoped_atomic_store_n:
4251 case AtomicExpr::AO__atomic_clear:
4252 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4253 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4254 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4313 const unsigned NumForm = ClearByte + 1;
4314 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4315 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4323 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4324 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4325 "need to update code for modified forms");
4326 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4327 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4328 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4329 "need to update code for modified C11 atomics");
4330 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4331 Op <= AtomicExpr::AO__opencl_atomic_store;
4332 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4333 Op <= AtomicExpr::AO__hip_atomic_store;
4334 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4335 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4336 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4337 Op <= AtomicExpr::AO__c11_atomic_store) ||
4339 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4340 Op == AtomicExpr::AO__atomic_store_n ||
4341 Op == AtomicExpr::AO__atomic_exchange_n ||
4342 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4343 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4344 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4345 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4346 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4350 enum ArithOpExtraValueType {
4355 unsigned ArithAllows = AOEVT_None;
4358 case AtomicExpr::AO__c11_atomic_init:
4359 case AtomicExpr::AO__opencl_atomic_init:
4363 case AtomicExpr::AO__c11_atomic_load:
4364 case AtomicExpr::AO__opencl_atomic_load:
4365 case AtomicExpr::AO__hip_atomic_load:
4366 case AtomicExpr::AO__atomic_load_n:
4367 case AtomicExpr::AO__scoped_atomic_load_n:
4371 case AtomicExpr::AO__atomic_load:
4372 case AtomicExpr::AO__scoped_atomic_load:
4376 case AtomicExpr::AO__c11_atomic_store:
4377 case AtomicExpr::AO__opencl_atomic_store:
4378 case AtomicExpr::AO__hip_atomic_store:
4379 case AtomicExpr::AO__atomic_store:
4380 case AtomicExpr::AO__atomic_store_n:
4381 case AtomicExpr::AO__scoped_atomic_store:
4382 case AtomicExpr::AO__scoped_atomic_store_n:
4385 case AtomicExpr::AO__atomic_fetch_add:
4386 case AtomicExpr::AO__atomic_fetch_sub:
4387 case AtomicExpr::AO__atomic_add_fetch:
4388 case AtomicExpr::AO__atomic_sub_fetch:
4389 case AtomicExpr::AO__scoped_atomic_fetch_add:
4390 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4391 case AtomicExpr::AO__scoped_atomic_add_fetch:
4392 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4393 case AtomicExpr::AO__c11_atomic_fetch_add:
4394 case AtomicExpr::AO__c11_atomic_fetch_sub:
4395 case AtomicExpr::AO__opencl_atomic_fetch_add:
4396 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4397 case AtomicExpr::AO__hip_atomic_fetch_add:
4398 case AtomicExpr::AO__hip_atomic_fetch_sub:
4399 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4402 case AtomicExpr::AO__atomic_fetch_max:
4403 case AtomicExpr::AO__atomic_fetch_min:
4404 case AtomicExpr::AO__atomic_max_fetch:
4405 case AtomicExpr::AO__atomic_min_fetch:
4406 case AtomicExpr::AO__scoped_atomic_fetch_max:
4407 case AtomicExpr::AO__scoped_atomic_fetch_min:
4408 case AtomicExpr::AO__scoped_atomic_max_fetch:
4409 case AtomicExpr::AO__scoped_atomic_min_fetch:
4410 case AtomicExpr::AO__c11_atomic_fetch_max:
4411 case AtomicExpr::AO__c11_atomic_fetch_min:
4412 case AtomicExpr::AO__opencl_atomic_fetch_max:
4413 case AtomicExpr::AO__opencl_atomic_fetch_min:
4414 case AtomicExpr::AO__hip_atomic_fetch_max:
4415 case AtomicExpr::AO__hip_atomic_fetch_min:
4416 ArithAllows = AOEVT_FP;
4419 case AtomicExpr::AO__c11_atomic_fetch_and:
4420 case AtomicExpr::AO__c11_atomic_fetch_or:
4421 case AtomicExpr::AO__c11_atomic_fetch_xor:
4422 case AtomicExpr::AO__hip_atomic_fetch_and:
4423 case AtomicExpr::AO__hip_atomic_fetch_or:
4424 case AtomicExpr::AO__hip_atomic_fetch_xor:
4425 case AtomicExpr::AO__c11_atomic_fetch_nand:
4426 case AtomicExpr::AO__opencl_atomic_fetch_and:
4427 case AtomicExpr::AO__opencl_atomic_fetch_or:
4428 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4429 case AtomicExpr::AO__atomic_fetch_and:
4430 case AtomicExpr::AO__atomic_fetch_or:
4431 case AtomicExpr::AO__atomic_fetch_xor:
4432 case AtomicExpr::AO__atomic_fetch_nand:
4433 case AtomicExpr::AO__atomic_and_fetch:
4434 case AtomicExpr::AO__atomic_or_fetch:
4435 case AtomicExpr::AO__atomic_xor_fetch:
4436 case AtomicExpr::AO__atomic_nand_fetch:
4437 case AtomicExpr::AO__scoped_atomic_fetch_and:
4438 case AtomicExpr::AO__scoped_atomic_fetch_or:
4439 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4440 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4441 case AtomicExpr::AO__scoped_atomic_and_fetch:
4442 case AtomicExpr::AO__scoped_atomic_or_fetch:
4443 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4444 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4448 case AtomicExpr::AO__c11_atomic_exchange:
4449 case AtomicExpr::AO__hip_atomic_exchange:
4450 case AtomicExpr::AO__opencl_atomic_exchange:
4451 case AtomicExpr::AO__atomic_exchange_n:
4452 case AtomicExpr::AO__scoped_atomic_exchange_n:
4456 case AtomicExpr::AO__atomic_exchange:
4457 case AtomicExpr::AO__scoped_atomic_exchange:
4461 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4462 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4463 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4464 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4465 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4466 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4470 case AtomicExpr::AO__atomic_compare_exchange:
4471 case AtomicExpr::AO__atomic_compare_exchange_n:
4472 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4473 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4477 case AtomicExpr::AO__atomic_test_and_set:
4478 Form = TestAndSetByte;
4481 case AtomicExpr::AO__atomic_clear:
4486 unsigned AdjustedNumArgs = NumArgs[Form];
4487 if ((IsOpenCL || IsHIP || IsScoped) &&
4488 Op != AtomicExpr::AO__opencl_atomic_init)
4491 if (Args.size() < AdjustedNumArgs) {
4492 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4493 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4496 }
else if (Args.size() > AdjustedNumArgs) {
4497 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4498 diag::err_typecheck_call_too_many_args)
4499 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4505 Expr *Ptr = Args[0];
4510 Ptr = ConvertedPtr.
get();
4513 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4523 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4529 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4535 }
else if (Form != Load && Form != LoadCopy) {
4537 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4543 if (Form != TestAndSetByte && Form != ClearByte) {
4546 diag::err_incomplete_type))
4549 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4550 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4560 pointerType->getPointeeType().getCVRQualifiers());
4570 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4579 auto IsAllowedValueType = [&](
QualType ValType,
4580 unsigned AllowedType) ->
bool {
4584 return AllowedType & AOEVT_Pointer;
4589 &
Context.getTargetInfo().getLongDoubleFormat() ==
4590 &llvm::APFloat::x87DoubleExtended())
4594 if (!IsAllowedValueType(ValType, ArithAllows)) {
4595 auto DID = ArithAllows & AOEVT_FP
4596 ? (ArithAllows & AOEVT_Pointer
4597 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4598 : diag::err_atomic_op_needs_atomic_int_or_fp)
4599 : diag::err_atomic_op_needs_atomic_int;
4606 diag::err_incomplete_type)) {
4612 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4623 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4639 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4651 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4654 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4660 bool IsPassedByAddress =
false;
4661 if (!IsC11 && !IsHIP && !IsN) {
4663 IsPassedByAddress =
true;
4668 APIOrderedArgs.push_back(Args[0]);
4672 APIOrderedArgs.push_back(Args[1]);
4678 APIOrderedArgs.push_back(Args[2]);
4679 APIOrderedArgs.push_back(Args[1]);
4682 APIOrderedArgs.push_back(Args[2]);
4683 APIOrderedArgs.push_back(Args[3]);
4684 APIOrderedArgs.push_back(Args[1]);
4687 APIOrderedArgs.push_back(Args[2]);
4688 APIOrderedArgs.push_back(Args[4]);
4689 APIOrderedArgs.push_back(Args[1]);
4690 APIOrderedArgs.push_back(Args[3]);
4693 APIOrderedArgs.push_back(Args[2]);
4694 APIOrderedArgs.push_back(Args[4]);
4695 APIOrderedArgs.push_back(Args[5]);
4696 APIOrderedArgs.push_back(Args[1]);
4697 APIOrderedArgs.push_back(Args[3]);
4699 case TestAndSetByte:
4701 APIOrderedArgs.push_back(Args[1]);
4705 APIOrderedArgs.append(Args.begin(), Args.end());
4712 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4714 if (i < NumVals[Form] + 1) {
4727 assert(Form != Load);
4729 Ty =
Context.getPointerDiffType();
4732 else if (Form ==
Copy || Form == Xchg) {
4733 if (IsPassedByAddress) {
4740 Expr *ValArg = APIOrderedArgs[i];
4747 AS = PtrTy->getPointeeType().getAddressSpace();
4756 if (IsPassedByAddress)
4776 APIOrderedArgs[i] = Arg.
get();
4781 SubExprs.push_back(Ptr);
4785 SubExprs.push_back(APIOrderedArgs[1]);
4788 case TestAndSetByte:
4790 SubExprs.push_back(APIOrderedArgs[1]);
4796 SubExprs.push_back(APIOrderedArgs[2]);
4797 SubExprs.push_back(APIOrderedArgs[1]);
4801 SubExprs.push_back(APIOrderedArgs[3]);
4802 SubExprs.push_back(APIOrderedArgs[1]);
4803 SubExprs.push_back(APIOrderedArgs[2]);
4806 SubExprs.push_back(APIOrderedArgs[3]);
4807 SubExprs.push_back(APIOrderedArgs[1]);
4808 SubExprs.push_back(APIOrderedArgs[4]);
4809 SubExprs.push_back(APIOrderedArgs[2]);
4812 SubExprs.push_back(APIOrderedArgs[4]);
4813 SubExprs.push_back(APIOrderedArgs[1]);
4814 SubExprs.push_back(APIOrderedArgs[5]);
4815 SubExprs.push_back(APIOrderedArgs[2]);
4816 SubExprs.push_back(APIOrderedArgs[3]);
4821 if (SubExprs.size() >= 2 && Form !=
Init) {
4822 std::optional<llvm::APSInt>
Success =
4823 SubExprs[1]->getIntegerConstantExpr(
Context);
4825 Diag(SubExprs[1]->getBeginLoc(),
4826 diag::warn_atomic_op_has_invalid_memory_order)
4827 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4828 << SubExprs[1]->getSourceRange();
4830 if (SubExprs.size() >= 5) {
4831 if (std::optional<llvm::APSInt> Failure =
4832 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4833 if (!llvm::is_contained(
4834 {llvm::AtomicOrderingCABI::relaxed,
4835 llvm::AtomicOrderingCABI::consume,
4836 llvm::AtomicOrderingCABI::acquire,
4837 llvm::AtomicOrderingCABI::seq_cst},
4838 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4839 Diag(SubExprs[3]->getBeginLoc(),
4840 diag::warn_atomic_op_has_invalid_memory_order)
4841 << 2 << SubExprs[3]->getSourceRange();
4848 auto *
Scope = Args[Args.size() - 1];
4849 if (std::optional<llvm::APSInt>
Result =
4851 if (!ScopeModel->isValid(
Result->getZExtValue()))
4852 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4853 <<
Scope->getSourceRange();
4855 SubExprs.push_back(
Scope);
4861 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4862 Op == AtomicExpr::AO__c11_atomic_store ||
4863 Op == AtomicExpr::AO__opencl_atomic_load ||
4864 Op == AtomicExpr::AO__hip_atomic_load ||
4865 Op == AtomicExpr::AO__opencl_atomic_store ||
4866 Op == AtomicExpr::AO__hip_atomic_store) &&
4867 Context.AtomicUsesUnsupportedLibcall(AE))
4869 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4870 Op == AtomicExpr::AO__opencl_atomic_load ||
4871 Op == AtomicExpr::AO__hip_atomic_load)
4876 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4892 assert(Fn &&
"builtin call without direct callee!");
4908 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
4915 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4917 <<
Callee->getSourceRange();
4926 Expr *FirstArg = TheCall->
getArg(0);
4930 FirstArg = FirstArgResult.
get();
4931 TheCall->
setArg(0, FirstArg);
4943 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4950 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4980 QualType ResultType = ValType;
4985#define BUILTIN_ROW(x) \
4986 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4987 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4989 static const unsigned BuiltinIndices[][5] = {
5014 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5015 case 1: SizeIndex = 0;
break;
5016 case 2: SizeIndex = 1;
break;
5017 case 4: SizeIndex = 2;
break;
5018 case 8: SizeIndex = 3;
break;
5019 case 16: SizeIndex = 4;
break;
5031 unsigned BuiltinIndex, NumFixed = 1;
5032 bool WarnAboutSemanticsChange =
false;
5033 switch (BuiltinID) {
5034 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5035 case Builtin::BI__sync_fetch_and_add:
5036 case Builtin::BI__sync_fetch_and_add_1:
5037 case Builtin::BI__sync_fetch_and_add_2:
5038 case Builtin::BI__sync_fetch_and_add_4:
5039 case Builtin::BI__sync_fetch_and_add_8:
5040 case Builtin::BI__sync_fetch_and_add_16:
5044 case Builtin::BI__sync_fetch_and_sub:
5045 case Builtin::BI__sync_fetch_and_sub_1:
5046 case Builtin::BI__sync_fetch_and_sub_2:
5047 case Builtin::BI__sync_fetch_and_sub_4:
5048 case Builtin::BI__sync_fetch_and_sub_8:
5049 case Builtin::BI__sync_fetch_and_sub_16:
5053 case Builtin::BI__sync_fetch_and_or:
5054 case Builtin::BI__sync_fetch_and_or_1:
5055 case Builtin::BI__sync_fetch_and_or_2:
5056 case Builtin::BI__sync_fetch_and_or_4:
5057 case Builtin::BI__sync_fetch_and_or_8:
5058 case Builtin::BI__sync_fetch_and_or_16:
5062 case Builtin::BI__sync_fetch_and_and:
5063 case Builtin::BI__sync_fetch_and_and_1:
5064 case Builtin::BI__sync_fetch_and_and_2:
5065 case Builtin::BI__sync_fetch_and_and_4:
5066 case Builtin::BI__sync_fetch_and_and_8:
5067 case Builtin::BI__sync_fetch_and_and_16:
5071 case Builtin::BI__sync_fetch_and_xor:
5072 case Builtin::BI__sync_fetch_and_xor_1:
5073 case Builtin::BI__sync_fetch_and_xor_2:
5074 case Builtin::BI__sync_fetch_and_xor_4:
5075 case Builtin::BI__sync_fetch_and_xor_8:
5076 case Builtin::BI__sync_fetch_and_xor_16:
5080 case Builtin::BI__sync_fetch_and_nand:
5081 case Builtin::BI__sync_fetch_and_nand_1:
5082 case Builtin::BI__sync_fetch_and_nand_2:
5083 case Builtin::BI__sync_fetch_and_nand_4:
5084 case Builtin::BI__sync_fetch_and_nand_8:
5085 case Builtin::BI__sync_fetch_and_nand_16:
5087 WarnAboutSemanticsChange =
true;
5090 case Builtin::BI__sync_add_and_fetch:
5091 case Builtin::BI__sync_add_and_fetch_1:
5092 case Builtin::BI__sync_add_and_fetch_2:
5093 case Builtin::BI__sync_add_and_fetch_4:
5094 case Builtin::BI__sync_add_and_fetch_8:
5095 case Builtin::BI__sync_add_and_fetch_16:
5099 case Builtin::BI__sync_sub_and_fetch:
5100 case Builtin::BI__sync_sub_and_fetch_1:
5101 case Builtin::BI__sync_sub_and_fetch_2:
5102 case Builtin::BI__sync_sub_and_fetch_4:
5103 case Builtin::BI__sync_sub_and_fetch_8:
5104 case Builtin::BI__sync_sub_and_fetch_16:
5108 case Builtin::BI__sync_and_and_fetch:
5109 case Builtin::BI__sync_and_and_fetch_1:
5110 case Builtin::BI__sync_and_and_fetch_2:
5111 case Builtin::BI__sync_and_and_fetch_4:
5112 case Builtin::BI__sync_and_and_fetch_8:
5113 case Builtin::BI__sync_and_and_fetch_16:
5117 case Builtin::BI__sync_or_and_fetch:
5118 case Builtin::BI__sync_or_and_fetch_1:
5119 case Builtin::BI__sync_or_and_fetch_2:
5120 case Builtin::BI__sync_or_and_fetch_4:
5121 case Builtin::BI__sync_or_and_fetch_8:
5122 case Builtin::BI__sync_or_and_fetch_16:
5126 case Builtin::BI__sync_xor_and_fetch:
5127 case Builtin::BI__sync_xor_and_fetch_1:
5128 case Builtin::BI__sync_xor_and_fetch_2:
5129 case Builtin::BI__sync_xor_and_fetch_4:
5130 case Builtin::BI__sync_xor_and_fetch_8:
5131 case Builtin::BI__sync_xor_and_fetch_16:
5135 case Builtin::BI__sync_nand_and_fetch:
5136 case Builtin::BI__sync_nand_and_fetch_1:
5137 case Builtin::BI__sync_nand_and_fetch_2:
5138 case Builtin::BI__sync_nand_and_fetch_4:
5139 case Builtin::BI__sync_nand_and_fetch_8:
5140 case Builtin::BI__sync_nand_and_fetch_16:
5142 WarnAboutSemanticsChange =
true;
5145 case Builtin::BI__sync_val_compare_and_swap:
5146 case Builtin::BI__sync_val_compare_and_swap_1:
5147 case Builtin::BI__sync_val_compare_and_swap_2:
5148 case Builtin::BI__sync_val_compare_and_swap_4:
5149 case Builtin::BI__sync_val_compare_and_swap_8:
5150 case Builtin::BI__sync_val_compare_and_swap_16:
5155 case Builtin::BI__sync_bool_compare_and_swap:
5156 case Builtin::BI__sync_bool_compare_and_swap_1:
5157 case Builtin::BI__sync_bool_compare_and_swap_2:
5158 case Builtin::BI__sync_bool_compare_and_swap_4:
5159 case Builtin::BI__sync_bool_compare_and_swap_8:
5160 case Builtin::BI__sync_bool_compare_and_swap_16:
5166 case Builtin::BI__sync_lock_test_and_set:
5167 case Builtin::BI__sync_lock_test_and_set_1:
5168 case Builtin::BI__sync_lock_test_and_set_2:
5169 case Builtin::BI__sync_lock_test_and_set_4:
5170 case Builtin::BI__sync_lock_test_and_set_8:
5171 case Builtin::BI__sync_lock_test_and_set_16:
5175 case Builtin::BI__sync_lock_release:
5176 case Builtin::BI__sync_lock_release_1:
5177 case Builtin::BI__sync_lock_release_2:
5178 case Builtin::BI__sync_lock_release_4:
5179 case Builtin::BI__sync_lock_release_8:
5180 case Builtin::BI__sync_lock_release_16:
5186 case Builtin::BI__sync_swap:
5187 case Builtin::BI__sync_swap_1:
5188 case Builtin::BI__sync_swap_2:
5189 case Builtin::BI__sync_swap_4:
5190 case Builtin::BI__sync_swap_8:
5191 case Builtin::BI__sync_swap_16:
5199 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5200 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5201 <<
Callee->getSourceRange();
5205 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5206 <<
Callee->getSourceRange();
5208 if (WarnAboutSemanticsChange) {
5209 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5210 <<
Callee->getSourceRange();
5215 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5216 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5217 FunctionDecl *NewBuiltinDecl;
5218 if (NewBuiltinID == BuiltinID)
5219 NewBuiltinDecl = FDecl;
5222 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5225 assert(Res.getFoundDecl());
5226 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5227 if (!NewBuiltinDecl)
5234 for (
unsigned i = 0; i != NumFixed; ++i) {
5263 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5265 CK_BuiltinFnToFnPtr);
5276 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5277 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5278 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5282 return TheCallResult;
5286 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5291 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5292 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5293 "Unexpected nontemporal load/store builtin!");
5294 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5295 unsigned numArgs = isStore ? 2 : 1;
5305 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5311 PointerArg = PointerArgResult.
get();
5312 TheCall->
setArg(numArgs - 1, PointerArg);
5316 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5329 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5336 return TheCallResult;
5348 return TheCallResult;
5355 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5357 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5358 Literal = ObjcLiteral->getString();
5362 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5369 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5370 InitializedEntity Entity =
5380 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5381 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5382 TT.getArch() == llvm::Triple::aarch64_32);
5383 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5384 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5385 if (IsX64 || IsAArch64) {
5392 return S.
Diag(Fn->getBeginLoc(),
5393 diag::err_ms_va_start_used_in_sysv_function);
5400 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5401 return S.
Diag(Fn->getBeginLoc(),
5402 diag::err_va_start_used_in_wrong_abi_function)
5403 << !IsWindowsOrUEFI;
5409 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5417 bool IsVariadic =
false;
5420 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5421 IsVariadic =
Block->isVariadic();
5422 Params =
Block->parameters();
5423 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5426 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5427 IsVariadic = MD->isVariadic();
5429 Params = MD->parameters();
5432 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5436 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5441 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5446 *LastParam = Params.empty() ?
nullptr : Params.back();
5451bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5456 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5480 ParmVarDecl *LastParam;
5491 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5493 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5498 if (std::optional<llvm::APSInt> Val =
5500 Val &&
LangOpts.C23 && *Val == 0 &&
5501 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5502 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5509 SourceLocation ParamLoc;
5510 bool IsCRegister =
false;
5511 bool SecondArgIsLastNonVariadicArgument =
false;
5512 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5513 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5514 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5517 ParamLoc = PV->getLocation();
5523 if (!SecondArgIsLastNonVariadicArgument)
5525 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5526 else if (IsCRegister ||
Type->isReferenceType() ||
5527 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5530 if (!Context.isPromotableIntegerType(Type))
5532 const auto *ED = Type->getAsEnumDecl();
5535 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5537 unsigned Reason = 0;
5538 if (
Type->isReferenceType()) Reason = 1;
5539 else if (IsCRegister) Reason = 2;
5540 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5541 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5548 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5568 if (
Call->getNumArgs() < 3)
5570 diag::err_typecheck_call_too_few_args_at_least)
5571 << 0 << 3 <<
Call->getNumArgs()
5584 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5587 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5590 const QualType &ConstCharPtrTy =
5592 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5594 << Arg1->
getType() << ConstCharPtrTy << 1
5597 << 2 << Arg1->
getType() << ConstCharPtrTy;
5599 const QualType SizeTy =
Context.getSizeType();
5604 << Arg2->
getType() << SizeTy << 1
5607 << 3 << Arg2->
getType() << SizeTy;
5612bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5616 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5644 diag::err_typecheck_call_invalid_ordered_compare)
5652bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5653 unsigned BuiltinID) {
5658 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5659 BuiltinID == Builtin::BI__builtin_isinf ||
5660 BuiltinID == Builtin::BI__builtin_isinf_sign))
5664 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5665 BuiltinID == Builtin::BI__builtin_isunordered))
5669 bool IsFPClass = NumArgs == 2;
5672 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5676 for (
unsigned i = 0; i < FPArgNo; ++i) {
5677 Expr *Arg = TheCall->
getArg(i);
5690 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5698 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5703 OrigArg = Res.
get();
5709 OrigArg = Res.
get();
5711 TheCall->
setArg(FPArgNo, OrigArg);
5713 QualType VectorResultTy;
5714 QualType ElementTy = OrigArg->
getType();
5719 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5725 diag::err_typecheck_call_invalid_unary_fp)
5737 if (!VectorResultTy.
isNull())
5738 ResultTy = VectorResultTy;
5747bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5752 for (
unsigned I = 0; I != 2; ++I) {
5753 Expr *Arg = TheCall->
getArg(I);
5763 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5778 Expr *Real = TheCall->
getArg(0);
5779 Expr *Imag = TheCall->
getArg(1);
5782 diag::err_typecheck_call_different_arg_types)
5797 diag::err_typecheck_call_too_few_args_at_least)
5798 << 0 << 2 << NumArgs
5805 unsigned NumElements = 0;
5820 unsigned NumResElements = NumArgs - 2;
5829 diag::err_vec_builtin_incompatible_vector)
5834 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
5836 diag::err_vec_builtin_incompatible_vector)
5841 }
else if (NumElements != NumResElements) {
5844 ?
Context.getExtVectorType(EltType, NumResElements)
5845 :
Context.getVectorType(EltType, NumResElements,
5850 for (
unsigned I = 2; I != NumArgs; ++I) {
5858 diag::err_shufflevector_nonconstant_argument)
5864 else if (
Result->getActiveBits() > 64 ||
5865 Result->getZExtValue() >= NumElements * 2)
5867 diag::err_shufflevector_argument_too_large)
5892 diag::err_convertvector_non_vector)
5895 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5897 <<
"__builtin_convertvector");
5902 if (SrcElts != DstElts)
5904 diag::err_convertvector_incompatible_vector)
5912bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5917 diag::err_typecheck_call_too_many_args_at_most)
5918 << 0 << 3 << NumArgs << 0
5923 for (
unsigned i = 1; i != NumArgs; ++i)
5930bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5931 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
5932 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5942 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5952bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5953 Expr *Arg = TheCall->
getArg(0);
5964bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5966 Expr *Arg = TheCall->
getArg(1);
5970 if (
const auto *UE =
5972 if (UE->getKind() == UETT_AlignOf ||
5973 UE->getKind() == UETT_PreferredAlignOf)
5979 if (!
Result.isPowerOf2())
5980 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5987 if (
Result > std::numeric_limits<int32_t>::max())
5995bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6000 Expr *FirstArg = TheCall->
getArg(0);
6006 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6010 TheCall->
setArg(0, FirstArgResult.
get());
6014 Expr *SecondArg = TheCall->
getArg(1);
6022 if (!
Result.isPowerOf2())
6023 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6035 Expr *ThirdArg = TheCall->
getArg(2);
6038 TheCall->
setArg(2, ThirdArg);
6044bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6045 unsigned BuiltinID =
6047 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6050 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6051 if (NumArgs < NumRequiredArgs) {
6052 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6053 << 0 << NumRequiredArgs << NumArgs
6056 if (NumArgs >= NumRequiredArgs + 0x100) {
6058 diag::err_typecheck_call_too_many_args_at_most)
6059 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6070 if (Arg.isInvalid())
6072 TheCall->
setArg(i, Arg.get());
6077 unsigned FormatIdx = i;
6087 unsigned FirstDataArg = i;
6088 while (i < NumArgs) {
6106 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6108 bool Success = CheckFormatArguments(
6111 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6135 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6144 int High,
bool RangeIsError) {
6158 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6166 PDiag(diag::warn_argument_invalid_range)
6209 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6214 if (
Value.isNegative())
6225 if ((
Value & 0xFF) != 0)
6250 Result.setIsUnsigned(
true);
6255 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6275 Result.setIsUnsigned(
true);
6283 diag::err_argument_not_shifted_byte_or_xxff)
6287bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6288 if (!Context.getTargetInfo().hasSjLjLowering())
6289 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6300 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6306bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6307 if (!Context.getTargetInfo().hasSjLjLowering())
6308 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6313bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6328 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6333 diag::err_builtin_counted_by_ref_has_side_effects)
6336 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6337 if (!ME->isFlexibleArrayMemberLike(
6340 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6344 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6347 if (
const FieldDecl *CountFD = FAMDecl->findCountedByField()) {
6354 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6364bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6366 const CallExpr *CE =
6375 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6380 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6385 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6389 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6393 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6403class UncoveredArgHandler {
6404 enum {
Unknown = -1, AllCovered = -2 };
6406 signed FirstUncoveredArg =
Unknown;
6407 SmallVector<const Expr *, 4> DiagnosticExprs;
6410 UncoveredArgHandler() =
default;
6412 bool hasUncoveredArg()
const {
6413 return (FirstUncoveredArg >= 0);
6416 unsigned getUncoveredArg()
const {
6417 assert(hasUncoveredArg() &&
"no uncovered argument");
6418 return FirstUncoveredArg;
6421 void setAllCovered() {
6424 DiagnosticExprs.clear();
6425 FirstUncoveredArg = AllCovered;
6428 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6429 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6432 if (FirstUncoveredArg == AllCovered)
6437 if (NewFirstUncoveredArg == FirstUncoveredArg)
6438 DiagnosticExprs.push_back(StrExpr);
6439 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6440 DiagnosticExprs.clear();
6441 DiagnosticExprs.push_back(StrExpr);
6442 FirstUncoveredArg = NewFirstUncoveredArg;
6446 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6449enum StringLiteralCheckType {
6451 SLCT_UncheckedLiteral,
6459 bool AddendIsRight) {
6460 unsigned BitWidth = Offset.getBitWidth();
6461 unsigned AddendBitWidth = Addend.getBitWidth();
6463 if (Addend.isUnsigned()) {
6464 Addend = Addend.zext(++AddendBitWidth);
6465 Addend.setIsSigned(
true);
6468 if (AddendBitWidth > BitWidth) {
6469 Offset = Offset.sext(AddendBitWidth);
6470 BitWidth = AddendBitWidth;
6471 }
else if (BitWidth > AddendBitWidth) {
6472 Addend = Addend.sext(BitWidth);
6476 llvm::APSInt ResOffset = Offset;
6477 if (BinOpKind == BO_Add)
6478 ResOffset = Offset.sadd_ov(Addend, Ov);
6480 assert(AddendIsRight && BinOpKind == BO_Sub &&
6481 "operator must be add or sub with addend on the right");
6482 ResOffset = Offset.ssub_ov(Addend, Ov);
6488 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6489 "index (intermediate) result too big");
6490 Offset = Offset.sext(2 * BitWidth);
6491 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6503class FormatStringLiteral {
6504 const StringLiteral *FExpr;
6508 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6509 : FExpr(fexpr), Offset(Offset) {}
6511 const StringLiteral *getFormatString()
const {
return FExpr; }
6513 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6515 unsigned getByteLength()
const {
6516 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6519 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6526 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6527 bool isWide()
const {
return FExpr->
isWide(); }
6528 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6529 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6530 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6531 bool isPascal()
const {
return FExpr->
isPascal(); }
6533 SourceLocation getLocationOfByte(
6534 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6535 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6536 unsigned *StartTokenByteOffset =
nullptr)
const {
6538 StartToken, StartTokenByteOffset);
6541 SourceLocation getBeginLoc() const LLVM_READONLY {
6545 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6551 Sema &S,
const FormatStringLiteral *FExpr,
6556 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6557 bool IgnoreStringsWithoutSpecifiers);
6571 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6572 llvm::APSInt Offset,
bool IgnoreStringsWithoutSpecifiers =
false) {
6574 return SLCT_NotALiteral;
6576 assert(Offset.isSigned() &&
"invalid offset");
6579 return SLCT_NotALiteral;
6588 return SLCT_UncheckedLiteral;
6591 case Stmt::InitListExprClass:
6595 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6596 Type, CallType,
false, CheckedVarArgs,
6597 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6599 return SLCT_NotALiteral;
6600 case Stmt::BinaryConditionalOperatorClass:
6601 case Stmt::ConditionalOperatorClass: {
6610 bool CheckLeft =
true, CheckRight =
true;
6613 if (
C->getCond()->EvaluateAsBooleanCondition(
6625 StringLiteralCheckType Left;
6627 Left = SLCT_UncheckedLiteral;
6630 S, ReferenceFormatString,
C->getTrueExpr(), Args, APK, format_idx,
6631 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6632 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6633 if (Left == SLCT_NotALiteral || !CheckRight) {
6639 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6640 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6641 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6643 return (CheckLeft && Left < Right) ? Left : Right;
6646 case Stmt::ImplicitCastExprClass:
6650 case Stmt::OpaqueValueExprClass:
6655 return SLCT_NotALiteral;
6657 case Stmt::PredefinedExprClass:
6661 return SLCT_UncheckedLiteral;
6663 case Stmt::DeclRefExprClass: {
6669 bool isConstant =
false;
6673 isConstant = AT->getElementType().isConstant(S.
Context);
6675 isConstant =
T.isConstant(S.
Context) &&
6676 PT->getPointeeType().isConstant(S.
Context);
6677 }
else if (
T->isObjCObjectPointerType()) {
6680 isConstant =
T.isConstant(S.
Context);
6684 if (
const Expr *
Init = VD->getAnyInitializer()) {
6687 if (InitList->isStringLiteralInit())
6688 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6691 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6692 firstDataArg,
Type, CallType,
6693 false, CheckedVarArgs, UncoveredArg, Offset);
6744 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6745 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6746 for (
const auto *PVFormatMatches :
6747 D->specific_attrs<FormatMatchesAttr>()) {
6752 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6756 S.
Diag(Args[format_idx]->getBeginLoc(),
6757 diag::warn_format_string_type_incompatible)
6758 << PVFormatMatches->getType()->getName()
6760 if (!InFunctionCall) {
6761 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6762 diag::note_format_string_defined);
6764 return SLCT_UncheckedLiteral;
6767 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6768 Args, APK, format_idx, firstDataArg,
Type, CallType,
6769 false, CheckedVarArgs, UncoveredArg,
6770 Offset, IgnoreStringsWithoutSpecifiers);
6774 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6777 PVFormat->getFirstArg(), &CallerFSI))
6779 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6783 S.
Diag(Args[format_idx]->getBeginLoc(),
6784 diag::warn_format_string_type_incompatible)
6785 << PVFormat->getType()->getName()
6787 if (!InFunctionCall) {
6790 return SLCT_UncheckedLiteral;
6803 return SLCT_UncheckedLiteral;
6811 return SLCT_NotALiteral;
6814 case Stmt::CallExprClass:
6815 case Stmt::CXXMemberCallExprClass: {
6819 StringLiteralCheckType CommonResult;
6820 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6821 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6823 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6824 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6825 Offset, IgnoreStringsWithoutSpecifiers);
6827 CommonResult = Result;
6832 return CommonResult;
6834 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6836 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6837 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6840 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6841 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6842 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6848 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6849 Type, CallType,
false, CheckedVarArgs,
6850 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6851 return SLCT_NotALiteral;
6853 case Stmt::ObjCMessageExprClass: {
6855 if (
const auto *MD = ME->getMethodDecl()) {
6856 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6865 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6867 MD->getSelector().isKeywordSelector(
6868 {
"localizedStringForKey",
"value",
"table"})) {
6869 IgnoreStringsWithoutSpecifiers =
true;
6872 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6874 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6875 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6876 Offset, IgnoreStringsWithoutSpecifiers);
6880 return SLCT_NotALiteral;
6882 case Stmt::ObjCStringLiteralClass:
6883 case Stmt::StringLiteralClass: {
6892 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6895 return SLCT_NotALiteral;
6897 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6899 format_idx, firstDataArg,
Type, InFunctionCall,
6900 CallType, CheckedVarArgs, UncoveredArg,
6901 IgnoreStringsWithoutSpecifiers);
6902 return SLCT_CheckedLiteral;
6905 return SLCT_NotALiteral;
6907 case Stmt::BinaryOperatorClass: {
6921 if (LIsInt != RIsInt) {
6925 if (BinOpKind == BO_Add) {
6938 return SLCT_NotALiteral;
6940 case Stmt::UnaryOperatorClass: {
6942 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6943 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6945 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6955 return SLCT_NotALiteral;
6959 return SLCT_NotALiteral;
6970 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6971 if (isa_and_nonnull<StringLiteral>(LVE))
6992 return "freebsd_kprintf";
7001 return llvm::StringSwitch<FormatStringType>(Flavor)
7003 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7008 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7024bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7028 llvm::SmallBitVector &CheckedVarArgs) {
7029 FormatStringInfo FSI;
7033 return CheckFormatArguments(
7034 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7039bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7043 llvm::SmallBitVector &CheckedVarArgs) {
7044 FormatStringInfo FSI;
7048 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7049 Format->getFormatString(), FSI.FormatIdx,
7051 CallType, Loc, Range, CheckedVarArgs);
7059 unsigned format_idx,
unsigned firstDataArg,
7063 llvm::SmallBitVector &CheckedVarArgs) {
7065 if (format_idx >= Args.size()) {
7066 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7070 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7084 UncoveredArgHandler UncoveredArg;
7086 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7087 firstDataArg,
Type, CallType,
7088 true, CheckedVarArgs, UncoveredArg,
7089 llvm::APSInt(64,
false) = 0);
7092 if (UncoveredArg.hasUncoveredArg()) {
7093 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7094 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7095 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7098 if (CT != SLCT_NotALiteral)
7100 return CT == SLCT_CheckedLiteral;
7111 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7118 if (Args.size() == firstDataArg) {
7119 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7127 Diag(FormatLoc, diag::note_format_security_fixit)
7131 Diag(FormatLoc, diag::note_format_security_fixit)
7136 Diag(FormatLoc, diag::warn_format_nonliteral)
7147 const FormatStringLiteral *FExpr;
7148 const Expr *OrigFormatExpr;
7150 const unsigned FirstDataArg;
7151 const unsigned NumDataArgs;
7154 ArrayRef<const Expr *> Args;
7156 llvm::SmallBitVector CoveredArgs;
7157 bool usesPositionalArgs =
false;
7158 bool atFirstArg =
true;
7159 bool inFunctionCall;
7161 llvm::SmallBitVector &CheckedVarArgs;
7162 UncoveredArgHandler &UncoveredArg;
7165 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7167 unsigned firstDataArg,
unsigned numDataArgs,
7169 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7171 llvm::SmallBitVector &CheckedVarArgs,
7172 UncoveredArgHandler &UncoveredArg)
7173 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7174 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7175 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7176 inFunctionCall(inFunctionCall), CallType(callType),
7177 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7178 CoveredArgs.resize(numDataArgs);
7179 CoveredArgs.reset();
7182 bool HasFormatArguments()
const {
7187 void DoneProcessing();
7189 void HandleIncompleteSpecifier(
const char *startSpecifier,
7190 unsigned specifierLen)
override;
7192 void HandleInvalidLengthModifier(
7193 const analyze_format_string::FormatSpecifier &FS,
7194 const analyze_format_string::ConversionSpecifier &CS,
7195 const char *startSpecifier,
unsigned specifierLen,
7198 void HandleNonStandardLengthModifier(
7199 const analyze_format_string::FormatSpecifier &FS,
7200 const char *startSpecifier,
unsigned specifierLen);
7202 void HandleNonStandardConversionSpecifier(
7203 const analyze_format_string::ConversionSpecifier &CS,
7204 const char *startSpecifier,
unsigned specifierLen);
7206 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7208 void HandleInvalidPosition(
const char *startSpecifier,
7209 unsigned specifierLen,
7212 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7214 void HandleNullChar(
const char *nullCharacter)
override;
7216 template <
typename Range>
7218 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7219 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7220 bool IsStringLocation, Range StringRange,
7221 ArrayRef<FixItHint> Fixit = {});
7224 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7225 const char *startSpec,
7226 unsigned specifierLen,
7227 const char *csStart,
unsigned csLen);
7229 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7230 const char *startSpec,
7231 unsigned specifierLen);
7233 SourceRange getFormatStringRange();
7234 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7235 unsigned specifierLen);
7236 SourceLocation getLocationOfByte(
const char *x);
7238 const Expr *getDataArg(
unsigned i)
const;
7240 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7241 const analyze_format_string::ConversionSpecifier &CS,
7242 const char *startSpecifier,
unsigned specifierLen,
7245 template <
typename Range>
7246 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7247 bool IsStringLocation, Range StringRange,
7248 ArrayRef<FixItHint> Fixit = {});
7253SourceRange CheckFormatHandler::getFormatStringRange() {
7258getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7260 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7268SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7273void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7274 unsigned specifierLen){
7275 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7276 getLocationOfByte(startSpecifier),
7278 getSpecifierRange(startSpecifier, specifierLen));
7281void CheckFormatHandler::HandleInvalidLengthModifier(
7284 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7296 getSpecifierRange(startSpecifier, specifierLen));
7298 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7299 << FixedLM->toString()
7304 if (DiagID == diag::warn_format_nonsensical_length)
7310 getSpecifierRange(startSpecifier, specifierLen),
7315void CheckFormatHandler::HandleNonStandardLengthModifier(
7317 const char *startSpecifier,
unsigned specifierLen) {
7326 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7330 getSpecifierRange(startSpecifier, specifierLen));
7332 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7333 << FixedLM->toString()
7337 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7341 getSpecifierRange(startSpecifier, specifierLen));
7345void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7347 const char *startSpecifier,
unsigned specifierLen) {
7353 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7357 getSpecifierRange(startSpecifier, specifierLen));
7360 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7361 << FixedCS->toString()
7364 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7368 getSpecifierRange(startSpecifier, specifierLen));
7372void CheckFormatHandler::HandlePosition(
const char *startPos,
7375 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7376 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7377 getLocationOfByte(startPos),
7379 getSpecifierRange(startPos, posLen));
7382void CheckFormatHandler::HandleInvalidPosition(
7383 const char *startSpecifier,
unsigned specifierLen,
7386 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7387 EmitFormatDiagnostic(
7388 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7389 getLocationOfByte(startSpecifier),
true,
7390 getSpecifierRange(startSpecifier, specifierLen));
7393void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7397 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7398 getLocationOfByte(startPos),
7400 getSpecifierRange(startPos, posLen));
7403void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7406 EmitFormatDiagnostic(
7407 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7408 getLocationOfByte(nullCharacter),
true,
7409 getFormatStringRange());
7415const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7416 return Args[FirstDataArg + i];
7419void CheckFormatHandler::DoneProcessing() {
7422 if (HasFormatArguments()) {
7425 signed notCoveredArg = CoveredArgs.find_first();
7426 if (notCoveredArg >= 0) {
7427 assert((
unsigned)notCoveredArg < NumDataArgs);
7428 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7430 UncoveredArg.setAllCovered();
7435void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7436 const Expr *ArgExpr) {
7437 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7449 for (
auto E : DiagnosticExprs)
7452 CheckFormatHandler::EmitFormatDiagnostic(
7453 S, IsFunctionCall, DiagnosticExprs[0],
7459CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7461 const char *startSpec,
7462 unsigned specifierLen,
7463 const char *csStart,
7465 bool keepGoing =
true;
7466 if (argIndex < NumDataArgs) {
7469 CoveredArgs.set(argIndex);
7485 std::string CodePointStr;
7486 if (!llvm::sys::locale::isPrint(*csStart)) {
7487 llvm::UTF32 CodePoint;
7488 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7489 const llvm::UTF8 *E =
7490 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7491 llvm::ConversionResult
Result =
7492 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7494 if (
Result != llvm::conversionOK) {
7495 unsigned char FirstChar = *csStart;
7496 CodePoint = (llvm::UTF32)FirstChar;
7499 llvm::raw_string_ostream
OS(CodePointStr);
7500 if (CodePoint < 256)
7501 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7502 else if (CodePoint <= 0xFFFF)
7503 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7505 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7509 EmitFormatDiagnostic(
7510 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7511 true, getSpecifierRange(startSpec, specifierLen));
7517CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7518 const char *startSpec,
7519 unsigned specifierLen) {
7520 EmitFormatDiagnostic(
7521 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7522 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7526CheckFormatHandler::CheckNumArgs(
7529 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7531 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7533 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7534 << (argIndex+1) << NumDataArgs)
7535 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7536 EmitFormatDiagnostic(
7537 PDiag, getLocationOfByte(CS.
getStart()),
true,
7538 getSpecifierRange(startSpecifier, specifierLen));
7542 UncoveredArg.setAllCovered();
7548template<
typename Range>
7551 bool IsStringLocation,
7554 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7555 Loc, IsStringLocation, StringRange, FixIt);
7585template <
typename Range>
7586void CheckFormatHandler::EmitFormatDiagnostic(
7587 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7590 if (InFunctionCall) {
7595 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7599 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7600 diag::note_format_string_defined);
7602 Note << StringRange;
7611class CheckPrintfHandler :
public CheckFormatHandler {
7613 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7615 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7617 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7619 llvm::SmallBitVector &CheckedVarArgs,
7620 UncoveredArgHandler &UncoveredArg)
7621 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7622 numDataArgs, beg, APK, Args, formatIdx,
7623 inFunctionCall, CallType, CheckedVarArgs,
7626 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7629 bool allowsObjCArg()
const {
7630 return FSType == FormatStringType::NSString ||
7631 FSType == FormatStringType::OSLog ||
7632 FSType == FormatStringType::OSTrace;
7635 bool HandleInvalidPrintfConversionSpecifier(
7636 const analyze_printf::PrintfSpecifier &FS,
7637 const char *startSpecifier,
7638 unsigned specifierLen)
override;
7640 void handleInvalidMaskType(StringRef MaskType)
override;
7642 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7643 const char *startSpecifier,
unsigned specifierLen,
7644 const TargetInfo &
Target)
override;
7645 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7646 const char *StartSpecifier,
7647 unsigned SpecifierLen,
7650 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7651 const char *startSpecifier,
unsigned specifierLen);
7652 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7653 const analyze_printf::OptionalAmount &Amt,
7655 const char *startSpecifier,
unsigned specifierLen);
7656 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7657 const analyze_printf::OptionalFlag &flag,
7658 const char *startSpecifier,
unsigned specifierLen);
7659 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7660 const analyze_printf::OptionalFlag &ignoredFlag,
7661 const analyze_printf::OptionalFlag &flag,
7662 const char *startSpecifier,
unsigned specifierLen);
7663 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7666 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7667 unsigned flagLen)
override;
7669 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7670 unsigned flagLen)
override;
7673 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7674 const char *flagsEnd,
7675 const char *conversionPosition)
override;
7680class EquatableFormatArgument {
7682 enum SpecifierSensitivity :
unsigned {
7689 enum FormatArgumentRole :
unsigned {
7697 analyze_format_string::ArgType ArgType;
7699 StringRef SpecifierLetter;
7700 CharSourceRange
Range;
7701 SourceLocation ElementLoc;
7702 FormatArgumentRole
Role : 2;
7703 SpecifierSensitivity Sensitivity : 2;
7704 unsigned Position : 14;
7705 unsigned ModifierFor : 14;
7707 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
7708 bool InFunctionCall)
const;
7711 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
7713 StringRef SpecifierLetter,
7714 analyze_format_string::ArgType ArgType,
7715 FormatArgumentRole
Role,
7716 SpecifierSensitivity Sensitivity,
unsigned Position,
7717 unsigned ModifierFor)
7718 : ArgType(ArgType), LengthMod(LengthMod),
7719 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7720 Role(
Role), Sensitivity(Sensitivity), Position(Position),
7721 ModifierFor(ModifierFor) {}
7723 unsigned getPosition()
const {
return Position; }
7724 SourceLocation getSourceLocation()
const {
return ElementLoc; }
7726 analyze_format_string::LengthModifier getLengthModifier()
const {
7727 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
7729 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7731 std::string buildFormatSpecifier()
const {
7733 llvm::raw_string_ostream(result)
7734 << getLengthModifier().toString() << SpecifierLetter;
7738 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
7739 const Expr *FmtExpr,
bool InFunctionCall)
const;
7743class DecomposePrintfHandler :
public CheckPrintfHandler {
7744 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
7747 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7748 const Expr *origFormatExpr,
7750 unsigned numDataArgs,
bool isObjC,
const char *beg,
7752 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7754 llvm::SmallBitVector &CheckedVarArgs,
7755 UncoveredArgHandler &UncoveredArg,
7756 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
7757 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7758 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7759 inFunctionCall, CallType, CheckedVarArgs,
7761 Specs(Specs), HadError(
false) {}
7765 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7767 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
7769 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7770 const char *startSpecifier,
7771 unsigned specifierLen,
7772 const TargetInfo &
Target)
override;
7777bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7779 unsigned specifierLen) {
7783 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
7785 startSpecifier, specifierLen,
7789void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7790 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7798 return T->isRecordType() ||
T->isComplexType();
7801bool CheckPrintfHandler::HandleAmount(
7803 const char *startSpecifier,
unsigned specifierLen) {
7805 if (HasFormatArguments()) {
7807 if (argIndex >= NumDataArgs) {
7808 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
7812 getSpecifierRange(startSpecifier, specifierLen));
7822 CoveredArgs.set(argIndex);
7823 const Expr *Arg = getDataArg(argIndex);
7834 ? diag::err_printf_asterisk_wrong_type
7835 : diag::warn_printf_asterisk_wrong_type;
7836 EmitFormatDiagnostic(S.
PDiag(DiagID)
7841 getSpecifierRange(startSpecifier, specifierLen));
7851void CheckPrintfHandler::HandleInvalidAmount(
7855 const char *startSpecifier,
7856 unsigned specifierLen) {
7866 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7870 getSpecifierRange(startSpecifier, specifierLen),
7876 const char *startSpecifier,
7877 unsigned specifierLen) {
7881 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7885 getSpecifierRange(startSpecifier, specifierLen),
7890void CheckPrintfHandler::HandleIgnoredFlag(
7894 const char *startSpecifier,
7895 unsigned specifierLen) {
7897 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7901 getSpecifierRange(startSpecifier, specifierLen),
7903 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7906void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7909 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7910 getLocationOfByte(startFlag),
7912 getSpecifierRange(startFlag, flagLen));
7915void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7918 auto Range = getSpecifierRange(startFlag, flagLen);
7919 StringRef flag(startFlag, flagLen);
7920 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7921 getLocationOfByte(startFlag),
7926void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7927 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7929 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7930 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7931 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
7932 getLocationOfByte(conversionPosition),
7938 const Expr *FmtExpr,
7939 bool InFunctionCall)
const {
7940 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
7941 ElementLoc,
true, Range);
7944bool EquatableFormatArgument::VerifyCompatible(
7945 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
7946 bool InFunctionCall)
const {
7951 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
7952 FmtExpr, InFunctionCall);
7953 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7957 if (
Role != FAR_Data) {
7958 if (ModifierFor !=
Other.ModifierFor) {
7961 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
7962 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
7963 FmtExpr, InFunctionCall);
7964 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7970 bool HadError =
false;
7971 if (Sensitivity !=
Other.Sensitivity) {
7974 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
7975 << Sensitivity <<
Other.Sensitivity,
7976 FmtExpr, InFunctionCall);
7977 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7978 << 0 <<
Other.Range;
7981 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
7985 case MK::MatchPromotion:
7989 case MK::NoMatchTypeConfusion:
7990 case MK::NoMatchPromotionTypeConfusion:
7992 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
7993 << buildFormatSpecifier()
7994 <<
Other.buildFormatSpecifier(),
7995 FmtExpr, InFunctionCall);
7996 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7997 << 0 <<
Other.Range;
8000 case MK::NoMatchPedantic:
8002 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8003 << buildFormatSpecifier()
8004 <<
Other.buildFormatSpecifier(),
8005 FmtExpr, InFunctionCall);
8006 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8007 << 0 <<
Other.Range;
8010 case MK::NoMatchSignedness:
8012 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8013 << buildFormatSpecifier()
8014 <<
Other.buildFormatSpecifier(),
8015 FmtExpr, InFunctionCall);
8016 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8017 << 0 <<
Other.Range;
8023bool DecomposePrintfHandler::GetSpecifiers(
8024 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8027 StringRef
Data = FSL->getString();
8028 const char *Str =
Data.data();
8029 llvm::SmallBitVector BV;
8030 UncoveredArgHandler UA;
8031 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8032 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8044 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8045 const EquatableFormatArgument &B) {
8046 return A.getPosition() < B.getPosition();
8051bool DecomposePrintfHandler::HandlePrintfSpecifier(
8054 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8069 const unsigned Unset = ~0;
8070 unsigned FieldWidthIndex = Unset;
8071 unsigned PrecisionIndex = Unset;
8075 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8076 FieldWidthIndex = Specs.size();
8077 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8078 getLocationOfByte(FieldWidth.getStart()),
8080 FieldWidth.getArgType(S.
Context),
8081 EquatableFormatArgument::FAR_FieldWidth,
8082 EquatableFormatArgument::SS_None,
8083 FieldWidth.usesPositionalArg()
8084 ? FieldWidth.getPositionalArgIndex() - 1
8090 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8091 PrecisionIndex = Specs.size();
8093 getSpecifierRange(startSpecifier, specifierLen),
8094 getLocationOfByte(Precision.getStart()),
8096 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8097 EquatableFormatArgument::SS_None,
8098 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8104 unsigned SpecIndex =
8106 if (FieldWidthIndex != Unset)
8107 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8108 if (PrecisionIndex != Unset)
8109 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8111 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8113 Sensitivity = EquatableFormatArgument::SS_Private;
8115 Sensitivity = EquatableFormatArgument::SS_Public;
8117 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8119 Sensitivity = EquatableFormatArgument::SS_None;
8122 getSpecifierRange(startSpecifier, specifierLen),
8125 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8130 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8135 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8136 SpecIndex + 1, SpecIndex);
8144template<
typename MemberKind>
8162 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8177 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8179 if ((*MI)->getMinRequiredArguments() == 0)
8187bool CheckPrintfHandler::checkForCStrMembers(
8194 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8197 if (
Method->getMinRequiredArguments() == 0 &&
8210bool CheckPrintfHandler::HandlePrintfSpecifier(
8224 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8225 startSpecifier, specifierLen);
8233 startSpecifier, specifierLen)) {
8238 startSpecifier, specifierLen)) {
8242 if (!CS.consumesDataArgument()) {
8250 if (argIndex < NumDataArgs) {
8254 CoveredArgs.set(argIndex);
8261 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8264 if (HasFormatArguments()) {
8266 CoveredArgs.set(argIndex + 1);
8269 const Expr *Ex = getDataArg(argIndex);
8273 : ArgType::CPointerTy;
8275 EmitFormatDiagnostic(
8276 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8280 getSpecifierRange(startSpecifier, specifierLen));
8283 Ex = getDataArg(argIndex + 1);
8286 EmitFormatDiagnostic(
8287 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8291 getSpecifierRange(startSpecifier, specifierLen));
8298 if (!allowsObjCArg() && CS.isObjCArg()) {
8299 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8306 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8313 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8314 getLocationOfByte(CS.getStart()),
8316 getSpecifierRange(startSpecifier, specifierLen));
8326 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8333 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8337 getSpecifierRange(startSpecifier, specifierLen));
8340 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8344 getSpecifierRange(startSpecifier, specifierLen));
8348 const llvm::Triple &Triple =
Target.getTriple();
8350 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8351 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8352 getLocationOfByte(CS.getStart()),
8354 getSpecifierRange(startSpecifier, specifierLen));
8360 startSpecifier, specifierLen);
8366 startSpecifier, specifierLen);
8372 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8373 getLocationOfByte(startSpecifier),
8375 getSpecifierRange(startSpecifier, specifierLen));
8384 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8386 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8395 startSpecifier, specifierLen);
8398 startSpecifier, specifierLen);
8403 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8404 diag::warn_format_nonsensical_length);
8406 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8408 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8409 diag::warn_format_non_standard_conversion_spec);
8412 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8415 if (!HasFormatArguments())
8418 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8421 const Expr *Arg = getDataArg(argIndex);
8425 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8437 case Stmt::ArraySubscriptExprClass:
8438 case Stmt::CallExprClass:
8439 case Stmt::CharacterLiteralClass:
8440 case Stmt::CXXBoolLiteralExprClass:
8441 case Stmt::DeclRefExprClass:
8442 case Stmt::FloatingLiteralClass:
8443 case Stmt::IntegerLiteralClass:
8444 case Stmt::MemberExprClass:
8445 case Stmt::ObjCArrayLiteralClass:
8446 case Stmt::ObjCBoolLiteralExprClass:
8447 case Stmt::ObjCBoxedExprClass:
8448 case Stmt::ObjCDictionaryLiteralClass:
8449 case Stmt::ObjCEncodeExprClass:
8450 case Stmt::ObjCIvarRefExprClass:
8451 case Stmt::ObjCMessageExprClass:
8452 case Stmt::ObjCPropertyRefExprClass:
8453 case Stmt::ObjCStringLiteralClass:
8454 case Stmt::ObjCSubscriptRefExprClass:
8455 case Stmt::ParenExprClass:
8456 case Stmt::StringLiteralClass:
8457 case Stmt::UnaryOperatorClass:
8464static std::pair<QualType, StringRef>
8471 StringRef Name = UserTy->getDecl()->getName();
8472 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8473 .Case(
"CFIndex", Context.getNSIntegerType())
8474 .Case(
"NSInteger", Context.getNSIntegerType())
8475 .Case(
"NSUInteger", Context.getNSUIntegerType())
8476 .Case(
"SInt32", Context.IntTy)
8477 .Case(
"UInt32", Context.UnsignedIntTy)
8481 return std::make_pair(CastTy, Name);
8483 TyTy = UserTy->desugar();
8487 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8489 PE->getSubExpr()->getType(),
8498 StringRef TrueName, FalseName;
8500 std::tie(TrueTy, TrueName) =
8502 CO->getTrueExpr()->getType(),
8504 std::tie(FalseTy, FalseName) =
8506 CO->getFalseExpr()->getType(),
8507 CO->getFalseExpr());
8509 if (TrueTy == FalseTy)
8510 return std::make_pair(TrueTy, TrueName);
8511 else if (TrueTy.
isNull())
8512 return std::make_pair(FalseTy, FalseName);
8513 else if (FalseTy.
isNull())
8514 return std::make_pair(TrueTy, TrueName);
8517 return std::make_pair(
QualType(), StringRef());
8536 From = VecTy->getElementType();
8538 To = VecTy->getElementType();
8549 diag::warn_format_conversion_argument_type_mismatch_signedness,
8553 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8562 const char *StartSpecifier,
8563 unsigned SpecifierLen,
8575 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8576 ExprTy = TET->getUnderlyingExpr()->getType();
8591 getSpecifierRange(StartSpecifier, SpecifierLen);
8593 llvm::raw_svector_ostream os(FSString);
8595 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8606 getSpecifierRange(StartSpecifier, SpecifierLen);
8607 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8617 if (
Match == ArgType::Match)
8621 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8630 E = ICE->getSubExpr();
8640 if (OrigMatch == ArgType::NoMatchSignedness &&
8641 ImplicitMatch != ArgType::NoMatchSignedness)
8648 if (ImplicitMatch == ArgType::Match)
8666 if (
Match == ArgType::MatchPromotion)
8670 if (
Match == ArgType::MatchPromotion) {
8674 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8675 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8679 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8680 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8681 Match = ImplicitMatch;
8682 assert(
Match != ArgType::MatchPromotion);
8685 bool IsEnum =
false;
8686 bool IsScopedEnum =
false;
8689 IntendedTy = ED->getIntegerType();
8690 if (!ED->isScoped()) {
8691 ExprTy = IntendedTy;
8696 IsScopedEnum =
true;
8703 if (isObjCContext() &&
8714 const llvm::APInt &
V = IL->getValue();
8724 if (TD->getUnderlyingType() == IntendedTy)
8734 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8742 if (!IsScopedEnum &&
8743 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8747 IntendedTy = CastTy;
8748 ShouldNotPrintDirectly =
true;
8753 PrintfSpecifier fixedFS = FS;
8760 llvm::raw_svector_ostream os(buf);
8763 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8765 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8771 llvm_unreachable(
"expected non-matching");
8773 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8776 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8779 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8782 Diag = diag::warn_format_conversion_argument_type_mismatch;
8803 llvm::raw_svector_ostream CastFix(CastBuf);
8804 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
8806 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
8812 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
8817 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
8839 if (ShouldNotPrintDirectly && !IsScopedEnum) {
8845 Name = TypedefTy->getDecl()->getName();
8849 ? diag::warn_format_argument_needs_cast_pedantic
8850 : diag::warn_format_argument_needs_cast;
8851 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
8862 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8863 : diag::warn_format_conversion_argument_type_mismatch;
8865 EmitFormatDiagnostic(
8877 bool EmitTypeMismatch =
false;
8886 llvm_unreachable(
"expected non-matching");
8888 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8891 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8894 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8898 ? diag::err_format_conversion_argument_type_mismatch
8899 : diag::warn_format_conversion_argument_type_mismatch;
8903 EmitFormatDiagnostic(
8912 EmitTypeMismatch =
true;
8914 EmitFormatDiagnostic(
8915 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
8916 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8920 checkForCStrMembers(AT, E);
8926 EmitTypeMismatch =
true;
8928 EmitFormatDiagnostic(
8929 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
8930 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8943 if (EmitTypeMismatch) {
8949 EmitFormatDiagnostic(
8950 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8956 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
8957 "format string specifier index out of range");
8958 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
8968class CheckScanfHandler :
public CheckFormatHandler {
8970 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8972 unsigned firstDataArg,
unsigned numDataArgs,
8974 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8976 llvm::SmallBitVector &CheckedVarArgs,
8977 UncoveredArgHandler &UncoveredArg)
8978 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8979 numDataArgs, beg, APK, Args, formatIdx,
8980 inFunctionCall, CallType, CheckedVarArgs,
8983 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
8984 const char *startSpecifier,
8985 unsigned specifierLen)
override;
8987 bool HandleInvalidScanfConversionSpecifier(
8988 const analyze_scanf::ScanfSpecifier &FS,
8989 const char *startSpecifier,
8990 unsigned specifierLen)
override;
8992 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
8997void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
8999 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9000 getLocationOfByte(end),
true,
9001 getSpecifierRange(start, end - start));
9004bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9006 const char *startSpecifier,
9007 unsigned specifierLen) {
9011 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9013 startSpecifier, specifierLen,
9017bool CheckScanfHandler::HandleScanfSpecifier(
9019 const char *startSpecifier,
9020 unsigned specifierLen) {
9034 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9035 startSpecifier, specifierLen);
9046 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9061 if (argIndex < NumDataArgs) {
9065 CoveredArgs.set(argIndex);
9071 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9072 diag::warn_format_nonsensical_length);
9074 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9076 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9077 diag::warn_format_non_standard_conversion_spec);
9080 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9083 if (!HasFormatArguments())
9086 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9090 const Expr *Ex = getDataArg(argIndex);
9108 ScanfSpecifier fixedFS = FS;
9113 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9115 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9116 : diag::warn_format_conversion_argument_type_mismatch;
9121 llvm::raw_svector_ostream os(buf);
9124 EmitFormatDiagnostic(
9129 getSpecifierRange(startSpecifier, specifierLen),
9131 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9138 getSpecifierRange(startSpecifier, specifierLen));
9148 const Expr *FmtExpr,
bool InFunctionCall) {
9149 bool HadError =
false;
9150 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9151 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9152 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9164 for (; FmtIter < FmtEnd; ++FmtIter) {
9168 if (FmtIter->getPosition() < RefIter->getPosition())
9172 if (FmtIter->getPosition() > RefIter->getPosition())
9176 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9180 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9181 return Arg.getPosition() != RefIter->getPosition();
9185 if (FmtIter < FmtEnd) {
9186 CheckFormatHandler::EmitFormatDiagnostic(
9187 S, InFunctionCall, FmtExpr,
9188 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9189 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9190 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9191 }
else if (RefIter < RefEnd) {
9192 CheckFormatHandler::EmitFormatDiagnostic(
9193 S, InFunctionCall, FmtExpr,
9194 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9197 << 1 << RefIter->getSourceRange();
9203 Sema &S,
const FormatStringLiteral *FExpr,
9208 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9209 bool IgnoreStringsWithoutSpecifiers) {
9211 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9212 CheckFormatHandler::EmitFormatDiagnostic(
9213 S, inFunctionCall, Args[format_idx],
9214 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9220 StringRef StrRef = FExpr->getString();
9221 const char *Str = StrRef.data();
9225 assert(
T &&
"String literal not of constant array type!");
9226 size_t TypeSize =
T->getZExtSize();
9227 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9228 const unsigned numDataArgs = Args.size() - firstDataArg;
9230 if (IgnoreStringsWithoutSpecifiers &&
9237 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9238 CheckFormatHandler::EmitFormatDiagnostic(
9239 S, inFunctionCall, Args[format_idx],
9240 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9241 FExpr->getBeginLoc(),
9247 if (StrLen == 0 && numDataArgs > 0) {
9248 CheckFormatHandler::EmitFormatDiagnostic(
9249 S, inFunctionCall, Args[format_idx],
9250 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9261 if (ReferenceFormatString ==
nullptr) {
9262 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9263 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9264 inFunctionCall, CallType, CheckedVarArgs,
9274 Type, ReferenceFormatString, FExpr->getFormatString(),
9275 inFunctionCall ?
nullptr : Args[format_idx]);
9278 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9279 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9280 CallType, CheckedVarArgs, UncoveredArg);
9300 FormatStringLiteral RefLit = AuthoritativeFormatString;
9301 FormatStringLiteral TestLit = TestedFormatString;
9303 bool DiagAtStringLiteral;
9304 if (FunctionCallArg) {
9305 Arg = FunctionCallArg;
9306 DiagAtStringLiteral =
false;
9308 Arg = TestedFormatString;
9309 DiagAtStringLiteral =
true;
9311 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9312 AuthoritativeFormatString,
Type,
9313 IsObjC,
true, RefArgs) &&
9314 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9315 DiagAtStringLiteral, FmtArgs)) {
9317 TestedFormatString, FmtArgs, Arg,
9318 DiagAtStringLiteral);
9331 FormatStringLiteral RefLit = Str;
9335 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9344 bool HadError =
false;
9345 auto Iter = Args.begin();
9346 auto End = Args.end();
9347 while (Iter != End) {
9348 const auto &FirstInGroup = *Iter;
9350 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9352 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9361 const char *Str = StrRef.data();
9364 assert(
T &&
"String literal not of constant array type!");
9365 size_t TypeSize =
T->getZExtSize();
9366 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9377 switch (AbsFunction) {
9381 case Builtin::BI__builtin_abs:
9382 return Builtin::BI__builtin_labs;
9383 case Builtin::BI__builtin_labs:
9384 return Builtin::BI__builtin_llabs;
9385 case Builtin::BI__builtin_llabs:
9388 case Builtin::BI__builtin_fabsf:
9389 return Builtin::BI__builtin_fabs;
9390 case Builtin::BI__builtin_fabs:
9391 return Builtin::BI__builtin_fabsl;
9392 case Builtin::BI__builtin_fabsl:
9395 case Builtin::BI__builtin_cabsf:
9396 return Builtin::BI__builtin_cabs;
9397 case Builtin::BI__builtin_cabs:
9398 return Builtin::BI__builtin_cabsl;
9399 case Builtin::BI__builtin_cabsl:
9402 case Builtin::BIabs:
9403 return Builtin::BIlabs;
9404 case Builtin::BIlabs:
9405 return Builtin::BIllabs;
9406 case Builtin::BIllabs:
9409 case Builtin::BIfabsf:
9410 return Builtin::BIfabs;
9411 case Builtin::BIfabs:
9412 return Builtin::BIfabsl;
9413 case Builtin::BIfabsl:
9416 case Builtin::BIcabsf:
9417 return Builtin::BIcabs;
9418 case Builtin::BIcabs:
9419 return Builtin::BIcabsl;
9420 case Builtin::BIcabsl:
9449 unsigned AbsFunctionKind) {
9450 unsigned BestKind = 0;
9451 uint64_t ArgSize = Context.getTypeSize(ArgType);
9452 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9455 if (Context.getTypeSize(ParamType) >= ArgSize) {
9458 else if (Context.hasSameType(ParamType, ArgType)) {
9474 if (
T->isIntegralOrEnumerationType())
9476 if (
T->isRealFloatingType())
9478 if (
T->isAnyComplexType())
9481 llvm_unreachable(
"Type not integer, floating, or complex");
9488 switch (ValueKind) {
9493 case Builtin::BI__builtin_fabsf:
9494 case Builtin::BI__builtin_fabs:
9495 case Builtin::BI__builtin_fabsl:
9496 case Builtin::BI__builtin_cabsf:
9497 case Builtin::BI__builtin_cabs:
9498 case Builtin::BI__builtin_cabsl:
9499 return Builtin::BI__builtin_abs;
9500 case Builtin::BIfabsf:
9501 case Builtin::BIfabs:
9502 case Builtin::BIfabsl:
9503 case Builtin::BIcabsf:
9504 case Builtin::BIcabs:
9505 case Builtin::BIcabsl:
9506 return Builtin::BIabs;
9512 case Builtin::BI__builtin_abs:
9513 case Builtin::BI__builtin_labs:
9514 case Builtin::BI__builtin_llabs:
9515 case Builtin::BI__builtin_cabsf:
9516 case Builtin::BI__builtin_cabs:
9517 case Builtin::BI__builtin_cabsl:
9518 return Builtin::BI__builtin_fabsf;
9519 case Builtin::BIabs:
9520 case Builtin::BIlabs:
9521 case Builtin::BIllabs:
9522 case Builtin::BIcabsf:
9523 case Builtin::BIcabs:
9524 case Builtin::BIcabsl:
9525 return Builtin::BIfabsf;
9531 case Builtin::BI__builtin_abs:
9532 case Builtin::BI__builtin_labs:
9533 case Builtin::BI__builtin_llabs:
9534 case Builtin::BI__builtin_fabsf:
9535 case Builtin::BI__builtin_fabs:
9536 case Builtin::BI__builtin_fabsl:
9537 return Builtin::BI__builtin_cabsf;
9538 case Builtin::BIabs:
9539 case Builtin::BIlabs:
9540 case Builtin::BIllabs:
9541 case Builtin::BIfabsf:
9542 case Builtin::BIfabs:
9543 case Builtin::BIfabsl:
9544 return Builtin::BIcabsf;
9547 llvm_unreachable(
"Unable to convert function");
9558 case Builtin::BI__builtin_abs:
9559 case Builtin::BI__builtin_fabs:
9560 case Builtin::BI__builtin_fabsf:
9561 case Builtin::BI__builtin_fabsl:
9562 case Builtin::BI__builtin_labs:
9563 case Builtin::BI__builtin_llabs:
9564 case Builtin::BI__builtin_cabs:
9565 case Builtin::BI__builtin_cabsf:
9566 case Builtin::BI__builtin_cabsl:
9567 case Builtin::BIabs:
9568 case Builtin::BIlabs:
9569 case Builtin::BIllabs:
9570 case Builtin::BIfabs:
9571 case Builtin::BIfabsf:
9572 case Builtin::BIfabsl:
9573 case Builtin::BIcabs:
9574 case Builtin::BIcabsf:
9575 case Builtin::BIcabsl:
9578 llvm_unreachable(
"Unknown Builtin type");
9584 unsigned AbsKind,
QualType ArgType) {
9585 bool EmitHeaderHint =
true;
9586 const char *HeaderName =
nullptr;
9587 std::string FunctionName;
9588 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9589 FunctionName =
"std::abs";
9590 if (ArgType->isIntegralOrEnumerationType()) {
9591 HeaderName =
"cstdlib";
9592 }
else if (ArgType->isRealFloatingType()) {
9593 HeaderName =
"cmath";
9595 llvm_unreachable(
"Invalid Type");
9604 for (
const auto *I : R) {
9607 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9609 FDecl = dyn_cast<FunctionDecl>(I);
9624 EmitHeaderHint =
false;
9642 EmitHeaderHint =
false;
9646 }
else if (!R.
empty()) {
9652 S.
Diag(Loc, diag::note_replace_abs_function)
9658 if (!EmitHeaderHint)
9661 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9665template <std::
size_t StrLen>
9667 const char (&Str)[StrLen]) {
9680 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9681 return llvm::is_contained(names, calleeName);
9686 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9687 "__builtin_nanf16",
"__builtin_nanf128"});
9689 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9690 "__builtin_inff16",
"__builtin_inff128"});
9692 llvm_unreachable(
"unknown MathCheck");
9696 if (FDecl->
getName() !=
"infinity")
9699 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9701 if (RDecl->
getName() !=
"numeric_limits")
9718 if (FPO.getNoHonorNaNs() &&
9721 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9722 << 1 << 0 <<
Call->getSourceRange();
9726 if (FPO.getNoHonorInfs() &&
9730 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9731 << 0 << 0 <<
Call->getSourceRange();
9735void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9737 if (
Call->getNumArgs() != 1)
9742 if (AbsKind == 0 && !IsStdAbs)
9745 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9746 QualType ParamType =
Call->getArg(0)->getType();
9751 std::string FunctionName =
9752 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9753 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9754 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9783 if (ArgValueKind == ParamValueKind) {
9784 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
9788 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9789 << FDecl << ArgType << ParamType;
9791 if (NewAbsKind == 0)
9795 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9804 if (NewAbsKind == 0)
9807 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
9808 << FDecl << ParamValueKind << ArgValueKind;
9811 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9817 if (!
Call || !FDecl)
return;
9821 if (
Call->getExprLoc().isMacroID())
return;
9824 if (
Call->getNumArgs() != 2)
return;
9827 if (!ArgList)
return;
9828 if (ArgList->size() != 1)
return;
9831 const auto& TA = ArgList->
get(0);
9833 QualType ArgType = TA.getAsType();
9837 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
9838 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
9839 if (!MTE)
return false;
9840 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
9841 if (!
Num)
return false;
9842 if (
Num->getValue() != 0)
return false;
9846 const Expr *FirstArg =
Call->getArg(0);
9847 const Expr *SecondArg =
Call->getArg(1);
9848 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
9849 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
9852 if (IsFirstArgZero == IsSecondArgZero)
return;
9857 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
9859 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
9860 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
9863 SourceRange RemovalRange;
9864 if (IsFirstArgZero) {
9865 RemovalRange = SourceRange(FirstRange.
getBegin(),
9872 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
9887 const auto *Size = dyn_cast<BinaryOperator>(E);
9892 if (!Size->isComparisonOp() && !Size->isLogicalOp())
9896 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
9897 << SizeRange << FnName;
9898 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
9903 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
9914 bool &IsContained) {
9916 const Type *Ty =
T->getBaseElementTypeUnsafe();
9917 IsContained =
false;
9930 for (
auto *FD : RD->
fields()) {
9943 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
9944 if (Unary->getKind() == UETT_SizeOf)
9953 if (!
SizeOf->isArgumentType())
9954 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
9961 return SizeOf->getTypeOfArgument();
9967struct SearchNonTrivialToInitializeField
9970 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
9972 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
9975 SourceLocation SL) {
9976 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9977 asDerived().visitArray(PDIK, AT, SL);
9981 Super::visitWithKind(PDIK, FT, SL);
9984 void visitARCStrong(QualType FT, SourceLocation SL) {
9987 void visitARCWeak(QualType FT, SourceLocation SL) {
9990 void visitStruct(QualType FT, SourceLocation SL) {
9995 const ArrayType *AT, SourceLocation SL) {
9996 visit(getContext().getBaseElementType(AT), SL);
9998 void visitTrivial(QualType FT, SourceLocation SL) {}
10000 static void diag(QualType RT,
const Expr *E, Sema &S) {
10001 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10010struct SearchNonTrivialToCopyField
10012 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10014 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10017 SourceLocation SL) {
10018 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10019 asDerived().visitArray(PCK, AT, SL);
10023 Super::visitWithKind(PCK, FT, SL);
10026 void visitARCStrong(QualType FT, SourceLocation SL) {
10029 void visitARCWeak(QualType FT, SourceLocation SL) {
10032 void visitPtrAuth(QualType FT, SourceLocation SL) {
10035 void visitStruct(QualType FT, SourceLocation SL) {
10040 SourceLocation SL) {
10041 visit(getContext().getBaseElementType(AT), SL);
10044 SourceLocation SL) {}
10045 void visitTrivial(QualType FT, SourceLocation SL) {}
10046 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10048 static void diag(QualType RT,
const Expr *E, Sema &S) {
10049 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10064 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10065 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10089 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10091 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10092 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10098 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10101 const Expr *SizeArg =
10102 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10104 auto isLiteralZero = [](
const Expr *E) {
10114 if (isLiteralZero(SizeArg) &&
10121 if (BId == Builtin::BIbzero ||
10124 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10125 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10126 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10127 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10128 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10136 if (BId == Builtin::BImemset &&
10140 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10141 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10146void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10153 unsigned ExpectedNumArgs =
10154 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10155 if (
Call->getNumArgs() < ExpectedNumArgs)
10158 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10159 BId == Builtin::BIstrndup ? 1 : 2);
10161 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10162 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10165 Call->getBeginLoc(),
Call->getRParenLoc()))
10174 llvm::FoldingSetNodeID SizeOfArgID;
10179 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10180 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10183 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10184 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10185 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10187 QualType DestTy = Dest->
getType();
10188 QualType PointeeTy;
10189 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10202 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10206 if (SizeOfArgID == llvm::FoldingSetNodeID())
10208 llvm::FoldingSetNodeID DestID;
10210 if (DestID == SizeOfArgID) {
10213 unsigned ActionIdx = 0;
10214 StringRef ReadableName = FnName->
getName();
10216 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10217 if (UnaryOp->getOpcode() == UO_AddrOf)
10226 SourceLocation SL = SizeOfArg->
getExprLoc();
10231 if (
SM.isMacroArgExpansion(SL)) {
10233 SL =
SM.getSpellingLoc(SL);
10234 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10236 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10241 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10248 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10259 if (SizeOfArgTy != QualType()) {
10261 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10263 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10264 << FnName << SizeOfArgTy << ArgIdx
10271 PointeeTy = DestTy;
10274 if (PointeeTy == QualType())
10279 if (
const CXXRecordDecl *ContainedRD =
10282 unsigned OperationType = 0;
10283 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10286 if (ArgIdx != 0 || IsCmp) {
10287 if (BId == Builtin::BImemcpy)
10289 else if(BId == Builtin::BImemmove)
10296 PDiag(diag::warn_dyn_class_memaccess)
10297 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10298 << IsContained << ContainedRD << OperationType
10299 <<
Call->getCallee()->getSourceRange());
10301 BId != Builtin::BImemset)
10304 PDiag(diag::warn_arc_object_memaccess)
10305 << ArgIdx << FnName << PointeeTy
10306 <<
Call->getCallee()->getSourceRange());
10313 bool NonTriviallyCopyableCXXRecord =
10317 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10320 PDiag(diag::warn_cstruct_memaccess)
10321 << ArgIdx << FnName << PointeeTy << 0);
10322 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10323 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10324 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10328 PDiag(diag::warn_cxxstruct_memaccess)
10329 << FnName << PointeeTy);
10330 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10333 PDiag(diag::warn_cstruct_memaccess)
10334 << ArgIdx << FnName << PointeeTy << 1);
10335 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10336 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10337 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10341 PDiag(diag::warn_cxxstruct_memaccess)
10342 << FnName << PointeeTy);
10351 PDiag(diag::note_bad_memaccess_silence)
10387 if (CAT->getZExtSize() <= 1)
10395void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10399 unsigned NumArgs =
Call->getNumArgs();
10400 if ((NumArgs != 3) && (NumArgs != 4))
10405 const Expr *CompareWithSrc =
nullptr;
10408 Call->getBeginLoc(),
Call->getRParenLoc()))
10413 CompareWithSrc = Ex;
10416 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10417 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10418 SizeCall->getNumArgs() == 1)
10423 if (!CompareWithSrc)
10430 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10434 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10435 if (!CompareWithSrcDRE ||
10439 const Expr *OriginalSizeArg =
Call->getArg(2);
10440 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10447 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10451 SmallString<128> sizeString;
10452 llvm::raw_svector_ostream
OS(sizeString);
10457 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10464 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10465 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10466 return D1->getDecl() == D2->getDecl();
10471 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10480void Sema::CheckStrncatArguments(
const CallExpr *CE,
10495 unsigned PatternType = 0;
10503 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10504 if (BE->getOpcode() == BO_Sub) {
10505 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10506 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10517 if (PatternType == 0)
10526 if (
SM.isMacroArgExpansion(SL)) {
10527 SL =
SM.getSpellingLoc(SL);
10528 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10533 QualType DstTy = DstArg->
getType();
10536 if (!isKnownSizeArray) {
10537 if (PatternType == 1)
10538 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10540 Diag(SL, diag::warn_strncat_src_size) << SR;
10544 if (PatternType == 1)
10545 Diag(SL, diag::warn_strncat_large_size) << SR;
10547 Diag(SL, diag::warn_strncat_src_size) << SR;
10549 SmallString<128> sizeString;
10550 llvm::raw_svector_ostream
OS(sizeString);
10558 Diag(SL, diag::note_strncat_wrong_size)
10563void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10572void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10574 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10575 const Decl *D = Lvalue->getDecl();
10576 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10577 if (!DD->getType()->isReferenceType())
10578 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10582 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10583 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10584 Lvalue->getMemberDecl());
10587void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10589 const auto *Lambda = dyn_cast<LambdaExpr>(
10594 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10595 << CalleeName << 2 ;
10598void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10600 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10601 if (Var ==
nullptr)
10605 << CalleeName << 0 << Var;
10608void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10611 llvm::raw_svector_ostream
OS(SizeString);
10614 if (Kind == clang::CK_BitCast &&
10615 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10617 if (Kind == clang::CK_IntegralToPointer &&
10619 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10622 switch (
Cast->getCastKind()) {
10623 case clang::CK_BitCast:
10624 case clang::CK_IntegralToPointer:
10625 case clang::CK_FunctionToPointerDecay:
10634 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10635 << CalleeName << 0 <<
OS.str();
10639void Sema::CheckFreeArguments(
const CallExpr *E) {
10640 const std::string CalleeName =
10645 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10647 case UnaryOperator::Opcode::UO_AddrOf:
10648 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10649 case UnaryOperator::Opcode::UO_Plus:
10650 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10655 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10657 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10659 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10660 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10661 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10667 << CalleeName << 1 ;
10672 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10673 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10677Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10686 Diag(ReturnLoc, diag::warn_null_ret)
10696 if (Op == OO_New || Op == OO_Array_New) {
10697 const FunctionProtoType *Proto
10701 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10707 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10712 if (
Context.getTargetInfo().getTriple().isPPC64())
10724 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10725 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10727 return FPLiteral && FPCast;
10730 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10736 llvm::APFloat TargetC = FPLiteral->
getValue();
10737 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10738 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10742 Diag(Loc, diag::warn_float_compare_literal)
10743 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10756 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10757 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10758 if (DRL->getDecl() == DRR->getDecl())
10766 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10767 if (FLL->isExact())
10769 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10770 if (FLR->isExact())
10774 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10775 CL &&
CL->getBuiltinCallee())
10778 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10779 CR && CR->getBuiltinCallee())
10783 Diag(Loc, diag::warn_floatingpoint_eq)
10804 IntRange(
unsigned Width,
bool NonNegative)
10805 : Width(Width), NonNegative(NonNegative) {}
10808 unsigned valueBits()
const {
10809 return NonNegative ? Width : Width - 1;
10813 static IntRange forBoolType() {
10814 return IntRange(1,
true);
10818 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
10819 return forValueOfCanonicalType(
C,
10824 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
10827 if (
const auto *VT = dyn_cast<VectorType>(
T))
10828 T = VT->getElementType().getTypePtr();
10829 if (
const auto *CT = dyn_cast<ComplexType>(
T))
10830 T = CT->getElementType().getTypePtr();
10831 if (
const auto *AT = dyn_cast<AtomicType>(
T))
10832 T = AT->getValueType().getTypePtr();
10834 if (!
C.getLangOpts().CPlusPlus) {
10837 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
10842 if (
Enum->isFixed()) {
10843 return IntRange(
C.getIntWidth(QualType(
T, 0)),
10844 !
Enum->getIntegerType()->isSignedIntegerType());
10847 unsigned NumPositive =
Enum->getNumPositiveBits();
10848 unsigned NumNegative =
Enum->getNumNegativeBits();
10850 if (NumNegative == 0)
10851 return IntRange(NumPositive,
true);
10853 return IntRange(std::max(NumPositive + 1, NumNegative),
10857 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10858 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10871 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
10874 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
10875 T = VT->getElementType().getTypePtr();
10876 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
10877 T = CT->getElementType().getTypePtr();
10878 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
10879 T = AT->getValueType().getTypePtr();
10881 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
10883 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10884 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10893 static IntRange join(IntRange L, IntRange R) {
10894 bool Unsigned = L.NonNegative && R.NonNegative;
10895 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
10896 L.NonNegative && R.NonNegative);
10900 static IntRange bit_and(IntRange L, IntRange R) {
10901 unsigned Bits = std::max(L.Width, R.Width);
10902 bool NonNegative =
false;
10903 if (L.NonNegative) {
10904 Bits = std::min(Bits, L.Width);
10905 NonNegative =
true;
10907 if (R.NonNegative) {
10908 Bits = std::min(Bits, R.Width);
10909 NonNegative =
true;
10911 return IntRange(Bits, NonNegative);
10915 static IntRange sum(IntRange L, IntRange R) {
10916 bool Unsigned = L.NonNegative && R.NonNegative;
10917 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
10922 static IntRange difference(IntRange L, IntRange R) {
10926 bool CanWiden = !L.NonNegative || !R.NonNegative;
10927 bool Unsigned = L.NonNegative && R.Width == 0;
10928 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
10934 static IntRange product(IntRange L, IntRange R) {
10938 bool CanWiden = !L.NonNegative && !R.NonNegative;
10939 bool Unsigned = L.NonNegative && R.NonNegative;
10940 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
10945 static IntRange rem(IntRange L, IntRange R) {
10949 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
10957 if (value.isSigned() && value.isNegative())
10958 return IntRange(value.getSignificantBits(),
false);
10960 if (value.getBitWidth() > MaxWidth)
10961 value = value.trunc(MaxWidth);
10965 return IntRange(value.getActiveBits(),
true);
10969 if (result.
isInt())
10976 R = IntRange::join(R, El);
10984 return IntRange::join(R, I);
10999 Ty = AtomicRHS->getValueType();
11018 bool InConstantContext,
11019 bool Approximate) {
11030 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11031 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11035 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11037 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11038 CE->getCastKind() == CK_BooleanToSignedIntegral;
11041 if (!isIntegerCast)
11042 return OutputTypeRange;
11045 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11046 InConstantContext, Approximate);
11048 return std::nullopt;
11051 if (SubRange->Width >= OutputTypeRange.Width)
11052 return OutputTypeRange;
11056 return IntRange(SubRange->Width,
11057 SubRange->NonNegative || OutputTypeRange.NonNegative);
11060 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11063 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11065 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11066 InConstantContext, Approximate);
11071 Expr *TrueExpr = CO->getTrueExpr();
11073 return std::nullopt;
11075 std::optional<IntRange> L =
11078 return std::nullopt;
11080 Expr *FalseExpr = CO->getFalseExpr();
11082 return std::nullopt;
11084 std::optional<IntRange> R =
11087 return std::nullopt;
11089 return IntRange::join(*L, *R);
11092 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11093 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11095 switch (BO->getOpcode()) {
11097 llvm_unreachable(
"builtin <=> should have class type");
11108 return IntRange::forBoolType();
11137 Combine = IntRange::bit_and;
11145 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11146 if (I->getValue() == 1) {
11147 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11148 return IntRange(R.Width,
true);
11158 case BO_ShrAssign: {
11160 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11162 return std::nullopt;
11166 if (std::optional<llvm::APSInt> shift =
11167 BO->getRHS()->getIntegerConstantExpr(
C)) {
11168 if (shift->isNonNegative()) {
11169 if (shift->uge(L->Width))
11170 L->Width = (L->NonNegative ? 0 : 1);
11172 L->Width -= shift->getZExtValue();
11186 Combine = IntRange::sum;
11190 if (BO->getLHS()->getType()->isPointerType())
11193 Combine = IntRange::difference;
11198 Combine = IntRange::product;
11207 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11209 return std::nullopt;
11212 if (std::optional<llvm::APSInt> divisor =
11213 BO->getRHS()->getIntegerConstantExpr(
C)) {
11214 unsigned log2 = divisor->logBase2();
11215 if (
log2 >= L->Width)
11216 L->Width = (L->NonNegative ? 0 : 1);
11218 L->Width = std::min(L->Width -
log2, MaxWidth);
11226 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11228 return std::nullopt;
11230 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11234 Combine = IntRange::rem;
11246 unsigned opWidth =
C.getIntWidth(
T);
11248 InConstantContext, Approximate);
11250 return std::nullopt;
11253 InConstantContext, Approximate);
11255 return std::nullopt;
11257 IntRange
C = Combine(*L, *R);
11258 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11259 C.Width = std::min(
C.Width, MaxWidth);
11263 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11264 switch (UO->getOpcode()) {
11267 return IntRange::forBoolType();
11281 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11284 return std::nullopt;
11289 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11299 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11302 return std::nullopt;
11307 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11317 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11318 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11322 return IntRange(BitField->getBitWidthValue(),
11323 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11326 return std::nullopt;
11332 bool InConstantContext,
11333 bool Approximate) {
11342 const llvm::fltSemantics &Src,
11343 const llvm::fltSemantics &Tgt) {
11344 llvm::APFloat truncated = value;
11347 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11348 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11350 return truncated.bitwiseIsEqual(value);
11359 const llvm::fltSemantics &Src,
11360 const llvm::fltSemantics &Tgt) {
11377 bool IsListInit =
false);
11392 return MacroName !=
"YES" && MacroName !=
"NO" &&
11393 MacroName !=
"true" && MacroName !=
"false";
11401 (!E->
getType()->isSignedIntegerType() ||
11416struct PromotedRange {
11418 llvm::APSInt PromotedMin;
11420 llvm::APSInt PromotedMax;
11422 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11424 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11425 else if (R.Width >= BitWidth && !
Unsigned) {
11429 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11430 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11432 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11433 .extOrTrunc(BitWidth);
11434 PromotedMin.setIsUnsigned(
Unsigned);
11436 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11437 .extOrTrunc(BitWidth);
11438 PromotedMax.setIsUnsigned(
Unsigned);
11443 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11453 InRangeFlag = 0x40,
11456 Min =
LE | InRangeFlag,
11457 InRange = InRangeFlag,
11458 Max =
GE | InRangeFlag,
11461 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11466 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11467 Value.isUnsigned() == PromotedMin.isUnsigned());
11468 if (!isContiguous()) {
11469 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11470 if (
Value.isMinValue())
return Min;
11471 if (
Value.isMaxValue())
return Max;
11472 if (
Value >= PromotedMin)
return InRange;
11473 if (
Value <= PromotedMax)
return InRange;
11477 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11478 case -1:
return Less;
11479 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11481 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11482 case -1:
return InRange;
11483 case 0:
return Max;
11488 llvm_unreachable(
"impossible compare result");
11491 static std::optional<StringRef>
11493 if (Op == BO_Cmp) {
11495 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11497 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11498 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11499 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11500 return std::nullopt;
11507 }
else if (Op == BO_NE) {
11511 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11518 if (Op == BO_GE || Op == BO_LE)
11519 std::swap(TrueFlag, FalseFlag);
11522 return StringRef(
"true");
11524 return StringRef(
"false");
11525 return std::nullopt;
11532 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11533 if (ICE->getCastKind() != CK_IntegralCast &&
11534 ICE->getCastKind() != CK_NoOp)
11536 E = ICE->getSubExpr();
11545 enum ConstantValueKind {
11550 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11551 return BL->getValue() ? ConstantValueKind::LiteralTrue
11552 : ConstantValueKind::LiteralFalse;
11553 return ConstantValueKind::Miscellaneous;
11558 const llvm::APSInt &
Value,
11559 bool RhsConstant) {
11581 if (!OtherValueRange)
11586 OtherT = AT->getValueType();
11587 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11591 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11597 bool OtherIsBooleanDespiteType =
11599 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11600 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11604 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11605 Value.isUnsigned());
11606 auto Cmp = OtherPromotedValueRange.compare(
Value);
11607 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11613 bool TautologicalTypeCompare =
false;
11615 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11616 Value.isUnsigned());
11617 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11620 TautologicalTypeCompare =
true;
11628 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11637 bool InRange = Cmp & PromotedRange::InRangeFlag;
11643 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11644 Other->getType()->isUnsignedIntegerOrEnumerationType())
11645 TautologicalTypeCompare =
true;
11650 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11651 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11655 llvm::raw_svector_ostream OS(PrettySourceValue);
11657 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11658 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11660 OS << (BL->getValue() ?
"YES" :
"NO");
11665 if (!TautologicalTypeCompare) {
11667 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11673 if (IsObjCSignedCharBool) {
11675 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11676 << OS.str() << *Result);
11683 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11687 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11688 : diag::warn_tautological_bool_compare)
11690 << OtherIsBooleanDespiteType << *Result
11697 ? diag::warn_unsigned_enum_always_true_comparison
11698 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11699 : diag::warn_unsigned_always_true_comparison)
11700 : diag::warn_tautological_constant_compare;
11703 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11736 if (
T->isIntegralType(S.
Context)) {
11737 std::optional<llvm::APSInt> RHSValue =
11739 std::optional<llvm::APSInt> LHSValue =
11743 if (RHSValue && LHSValue)
11747 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11749 const bool RhsConstant = (
bool)RHSValue;
11750 Expr *Const = RhsConstant ? RHS : LHS;
11752 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11761 if (!
T->hasUnsignedIntegerRepresentation()) {
11775 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11777 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11783 Expr *signedOperand, *unsignedOperand;
11786 "unsigned comparison between two signed integer expressions?");
11787 signedOperand = LHS;
11788 unsignedOperand = RHS;
11790 signedOperand = RHS;
11791 unsignedOperand = LHS;
11797 std::optional<IntRange> signedRange =
11809 if (signedRange->NonNegative)
11821 if (!unsignedRange)
11826 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
11828 if (unsignedRange->Width < comparisonWidth)
11833 S.
PDiag(diag::warn_mixed_sign_comparison)
11852 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
11857 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
11858 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
11859 BitfieldEnumDecl->getNumNegativeBits() == 0) {
11860 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
11861 << BitfieldEnumDecl;
11868 Init->isValueDependent() ||
11869 Init->isTypeDependent())
11872 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
11882 const PreferredTypeAttr *PTAttr =
nullptr;
11884 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
11886 ED = PTAttr->getType()->getAsEnumDecl();
11894 bool SignedEnum = ED->getNumNegativeBits() > 0;
11901 unsigned DiagID = 0;
11902 if (SignedEnum && !SignedBitfield) {
11905 ? diag::warn_unsigned_bitfield_assigned_signed_enum
11907 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11908 }
else if (SignedBitfield && !SignedEnum &&
11909 ED->getNumPositiveBits() == FieldWidth) {
11912 ? diag::warn_signed_bitfield_enum_conversion
11913 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11916 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11921 << SignedEnum << TypeRange;
11923 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11930 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
11931 ED->getNumNegativeBits())
11932 : ED->getNumPositiveBits();
11935 if (BitsNeeded > FieldWidth) {
11939 ? diag::warn_bitfield_too_small_for_enum
11940 : diag::warn_preferred_type_bitfield_too_small_for_enum;
11941 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11945 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11953 llvm::APSInt
Value = Result.Val.getInt();
11955 unsigned OriginalWidth =
Value.getBitWidth();
11961 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
11962 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
11969 if (!
Value.isSigned() ||
Value.isNegative())
11970 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
11971 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
11972 OriginalWidth =
Value.getSignificantBits();
11974 if (OriginalWidth <= FieldWidth)
11978 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
11982 TruncatedValue = TruncatedValue.extend(OriginalWidth);
11983 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
11987 std::string PrettyTrunc =
toString(TruncatedValue, 10);
11989 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
11990 ? diag::warn_impcast_single_bit_bitield_precision_constant
11991 : diag::warn_impcast_bitfield_precision_constant)
11992 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
11993 <<
Init->getSourceRange();
12025 bool PruneControlFlow =
false) {
12032 if (
T.hasAddressSpace())
12034 if (PruneControlFlow) {
12048 bool PruneControlFlow =
false) {
12055 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
12060 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12061 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12066 llvm::APFloat
Value(0.0);
12072 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12077 diag::warn_impcast_float_integer, PruneWarnings);
12080 bool isExact =
false;
12083 T->hasUnsignedIntegerRepresentation());
12084 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12085 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12093 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12094 precision = (precision * 59 + 195) / 196;
12095 Value.toString(PrettySourceValue, precision);
12099 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12100 << PrettySourceValue);
12103 if (Result == llvm::APFloat::opOK && isExact) {
12104 if (IsLiteral)
return;
12105 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
12111 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12114 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12115 : diag::warn_impcast_float_to_integer_out_of_range,
12118 unsigned DiagID = 0;
12121 DiagID = diag::warn_impcast_literal_float_to_integer;
12122 }
else if (IntegerValue == 0) {
12123 if (
Value.isZero()) {
12125 diag::warn_impcast_float_integer, PruneWarnings);
12128 DiagID = diag::warn_impcast_float_to_integer_zero;
12130 if (IntegerValue.isUnsigned()) {
12131 if (!IntegerValue.isMaxValue()) {
12133 diag::warn_impcast_float_integer, PruneWarnings);
12136 if (!IntegerValue.isMaxSignedValue() &&
12137 !IntegerValue.isMinSignedValue()) {
12139 diag::warn_impcast_float_integer, PruneWarnings);
12143 DiagID = diag::warn_impcast_float_to_integer;
12148 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12150 IntegerValue.toString(PrettyTargetValue);
12152 if (PruneWarnings) {
12155 << E->
getType() <<
T.getUnqualifiedType()
12156 << PrettySourceValue << PrettyTargetValue
12160 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12169 "Must be compound assignment operation");
12180 ->getComputationResultType()
12187 if (ResultBT->isInteger())
12189 E->
getExprLoc(), diag::warn_impcast_float_integer);
12191 if (!ResultBT->isFloatingPoint())
12200 diag::warn_impcast_float_result_precision);
12205 if (!Range.Width)
return "0";
12207 llvm::APSInt ValueInRange =
Value;
12208 ValueInRange.setIsSigned(!Range.NonNegative);
12209 ValueInRange = ValueInRange.trunc(Range.Width);
12210 return toString(ValueInRange, 10);
12220 const Type *Source =
12222 if (
Target->isDependentType())
12225 const auto *FloatCandidateBT =
12226 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12227 const Type *BoolCandidateType = ToBool ?
Target : Source;
12230 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12235 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12241 S, TheCall->
getArg(I - 1),
false));
12243 S, TheCall->
getArg(I + 1),
false));
12248 diag::warn_impcast_floating_point_to_bool);
12263 if (!IsGNUNullExpr && !HasNullPtrType)
12267 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12268 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12271 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12284 if (IsGNUNullExpr && Loc.
isMacroID()) {
12287 if (MacroName ==
"NULL")
12295 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12309 const char FirstLiteralCharacter =
12311 if (FirstLiteralCharacter ==
'0')
12317 if (CC.
isValid() &&
T->isCharType()) {
12318 const char FirstContextCharacter =
12320 if (FirstContextCharacter ==
'{')
12328 const auto *IL = dyn_cast<IntegerLiteral>(E);
12330 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12331 if (UO->getOpcode() == UO_Minus)
12332 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12343 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12347 if (Opc == BO_Shl) {
12350 if (LHS && LHS->getValue() == 0)
12351 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12353 RHS->getValue().isNonNegative() &&
12355 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12356 << (Result.Val.getInt() != 0);
12358 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12365 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12370 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12371 (RHS->getValue() == 0 || RHS->getValue() == 1))
12374 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12375 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12383 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12389 if (Source->isChar16Type() &&
Target->isChar32Type())
12395 llvm::APSInt
Value(32);
12396 Value = Result.Val.getInt();
12397 bool IsASCII =
Value <= 0x7F;
12398 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12399 bool ConversionPreservesSemantics =
12400 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12402 if (!ConversionPreservesSemantics) {
12403 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12404 const llvm::APSInt &
Value) {
12405 if (
T->isChar8Type())
12406 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12407 if (
T->isChar16Type())
12408 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12409 assert(
T->isChar32Type());
12410 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12413 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12422 LosesPrecision ? diag::warn_impcast_unicode_precision
12423 : diag::warn_impcast_unicode_char_type);
12428 From =
Context.getCanonicalType(From);
12429 To =
Context.getCanonicalType(To);
12432 From = MaybePointee;
12439 if (FromFn->getCFIUncheckedCalleeAttr() &&
12440 !ToFn->getCFIUncheckedCalleeAttr())
12448 bool *ICContext,
bool IsListInit) {
12453 if (Source ==
Target)
return;
12454 if (
Target->isDependentType())
return;
12464 if (Source->isAtomicType())
12468 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12474 diag::warn_impcast_string_literal_to_bool);
12480 diag::warn_impcast_objective_c_literal_to_bool);
12482 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12492 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12495 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12497 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12506 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12508 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12513 if (
Target->isSveVLSBuiltinType() &&
12520 if (
Target->isRVVVLSBuiltinType() &&
12530 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12537 diag::warn_hlsl_impcast_vector_truncation);
12549 if (
auto VecTy = dyn_cast<VectorType>(
Target))
12550 Target = VecTy->getElementType().getTypePtr();
12560 ? diag::err_impcast_complex_scalar
12561 : diag::warn_impcast_complex_scalar);
12568 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12574 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12577 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12579 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12621 else if (Order < 0) {
12631 if (TargetBT && TargetBT->
isInteger()) {
12658 diag::warn_impcast_floating_point_to_bool);
12666 if (Source->isFixedPointType()) {
12667 if (
Target->isUnsaturatedFixedPointType()) {
12671 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12672 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12673 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12676 PDiag(diag::warn_impcast_fixed_point_range)
12677 <<
Value.toString() <<
T
12683 }
else if (
Target->isIntegerType()) {
12687 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12690 llvm::APSInt IntResult = FXResult.convertToInt(
12691 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12696 PDiag(diag::warn_impcast_fixed_point_range)
12697 << FXResult.toString() <<
T
12704 }
else if (
Target->isUnsaturatedFixedPointType()) {
12705 if (Source->isIntegerType()) {
12712 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12717 PDiag(diag::warn_impcast_fixed_point_range)
12738 unsigned int SourcePrecision =
SourceRange->Width;
12742 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12745 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12746 SourcePrecision > TargetPrecision) {
12748 if (std::optional<llvm::APSInt> SourceInt =
12753 llvm::APFloat TargetFloatValue(
12755 llvm::APFloat::opStatus ConversionStatus =
12756 TargetFloatValue.convertFromAPInt(
12758 llvm::APFloat::rmNearestTiesToEven);
12760 if (ConversionStatus != llvm::APFloat::opOK) {
12762 SourceInt->toString(PrettySourceValue, 10);
12764 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12768 PDiag(diag::warn_impcast_integer_float_precision_constant)
12769 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12775 diag::warn_impcast_integer_float_precision);
12784 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
12789 if (
Target->isBooleanType())
12793 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
12797 if (!Source->isIntegerType() || !
Target->isIntegerType())
12802 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
12805 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
12808 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
12813 if (!LikelySourceRange)
12816 IntRange SourceTypeRange =
12817 IntRange::forTargetOfCanonicalType(
Context, Source);
12818 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
12820 if (LikelySourceRange->Width > TargetRange.Width) {
12826 llvm::APSInt
Value(32);
12836 PDiag(diag::warn_impcast_integer_precision_constant)
12837 << PrettySourceValue << PrettyTargetValue
12847 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12848 if (UO->getOpcode() == UO_Minus)
12850 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
12853 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
12857 diag::warn_impcast_integer_precision);
12860 if (TargetRange.Width > SourceTypeRange.Width) {
12861 if (
auto *UO = dyn_cast<UnaryOperator>(E))
12862 if (UO->getOpcode() == UO_Minus)
12863 if (Source->isUnsignedIntegerType()) {
12864 if (
Target->isUnsignedIntegerType())
12866 diag::warn_impcast_high_order_zero_bits);
12867 if (
Target->isSignedIntegerType())
12869 diag::warn_impcast_nonnegative_result);
12873 if (TargetRange.Width == LikelySourceRange->Width &&
12874 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12875 Source->isSignedIntegerType()) {
12889 PDiag(diag::warn_impcast_integer_precision_constant)
12890 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12900 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
12901 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12902 LikelySourceRange->Width == TargetRange.Width))) {
12906 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
12908 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
12912 unsigned DiagID = diag::warn_impcast_integer_sign;
12920 DiagID = diag::warn_impcast_integer_sign_conditional;
12937 Source =
Context.getCanonicalType(SourceType).getTypePtr();
12939 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
12940 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
12941 if (SourceEnum->getDecl()->hasNameForLinkage() &&
12942 TargetEnum->getDecl()->hasNameForLinkage() &&
12943 SourceEnum != TargetEnum) {
12948 diag::warn_impcast_different_enum_types);
12962 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
12975 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
12976 TrueExpr = BCO->getCommon();
12978 bool Suspicious =
false;
12982 if (
T->isBooleanType())
12987 if (!Suspicious)
return;
12990 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
12997 Suspicious =
false;
13002 E->
getType(), CC, &Suspicious);
13019struct AnalyzeImplicitConversionsWorkItem {
13028 bool ExtraCheckForImplicitConversion,
13031 WorkList.push_back({E, CC,
false});
13033 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
13040 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13042 Expr *OrigE = Item.E;
13061 Expr *SourceExpr = E;
13066 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13067 if (
auto *Src = OVE->getSourceExpr())
13070 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13071 if (UO->getOpcode() == UO_Not &&
13072 UO->getSubExpr()->isKnownToHaveBooleanValue())
13073 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13077 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13078 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13079 BO->getLHS()->isKnownToHaveBooleanValue() &&
13080 BO->getRHS()->isKnownToHaveBooleanValue() &&
13081 BO->getLHS()->HasSideEffects(S.
Context) &&
13082 BO->getRHS()->HasSideEffects(S.
Context)) {
13093 if (SR.str() ==
"&" || SR.str() ==
"|") {
13095 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13096 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13099 BO->getOperatorLoc(),
13100 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13101 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13103 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13121 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13127 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13142 for (
auto *SE : POE->semantics())
13143 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13144 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13148 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13149 E = CE->getSubExpr();
13155 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13156 if (InitListE->getNumInits() == 1) {
13157 E = InitListE->getInit(0);
13164 WorkList.push_back({E, CC, IsListInit});
13168 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13169 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13173 if (OutArgE->isInOut())
13174 WorkList.push_back(
13175 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13176 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13182 if (BO->isComparisonOp())
13186 if (BO->getOpcode() == BO_Assign)
13189 if (BO->isAssignmentOp())
13205 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13207 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13211 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13212 if (ChildExpr == CSE->getOperand())
13218 if (IsLogicalAndOperator &&
13223 WorkList.push_back({ChildExpr, CC, IsListInit});
13237 if (
U->getOpcode() == UO_LNot) {
13239 }
else if (
U->getOpcode() != UO_AddrOf) {
13240 if (
U->getSubExpr()->getType()->isAtomicType())
13241 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13242 diag::warn_atomic_implicit_seq_cst);
13253 WorkList.push_back({OrigE, CC, IsListInit});
13254 while (!WorkList.empty())
13266 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13269 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13270 if (!M->getMemberDecl()->getType()->isReferenceType())
13272 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13273 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13275 FD =
Call->getDirectCallee();
13284 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13298 if (
SM.isMacroBodyExpansion(Loc))
13300 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13324 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13325 : diag::warn_this_bool_conversion;
13330 bool IsAddressOf =
false;
13332 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13333 if (UO->getOpcode() != UO_AddrOf)
13335 IsAddressOf =
true;
13336 E = UO->getSubExpr();
13340 unsigned DiagID = IsCompare
13341 ? diag::warn_address_of_reference_null_compare
13342 : diag::warn_address_of_reference_bool_conversion;
13350 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13353 llvm::raw_string_ostream S(Str);
13355 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13356 : diag::warn_cast_nonnull_to_bool;
13359 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13364 if (
auto *Callee =
Call->getDirectCallee()) {
13365 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13366 ComplainAboutNonnullParamOrCall(A);
13375 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13376 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13377 MRecordDecl && MRecordDecl->isLambda()) {
13380 << MRecordDecl->getSourceRange() << Range << IsEqual;
13390 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13391 D = M->getMemberDecl();
13399 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13402 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13403 ComplainAboutNonnullParamOrCall(A);
13407 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13411 auto ParamIter = llvm::find(FD->
parameters(), PV);
13413 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13417 ComplainAboutNonnullParamOrCall(
NonNull);
13422 if (ArgNo.getASTIndex() == ParamNo) {
13423 ComplainAboutNonnullParamOrCall(
NonNull);
13433 const bool IsArray =
T->isArrayType();
13434 const bool IsFunction =
T->isFunctionType();
13437 if (IsAddressOf && IsFunction) {
13442 if (!IsAddressOf && !IsFunction && !IsArray)
13447 llvm::raw_string_ostream S(Str);
13450 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13451 : diag::warn_impcast_pointer_to_bool;
13458 DiagType = AddressOf;
13459 else if (IsFunction)
13460 DiagType = FunctionPointer;
13462 DiagType = ArrayPointer;
13464 llvm_unreachable(
"Could not determine diagnostic.");
13466 << Range << IsEqual;
13479 if (ReturnType.
isNull())
13517 CheckArrayAccess(E);
13527void Sema::CheckForIntOverflow (
const Expr *E) {
13529 SmallVector<const Expr *, 2> Exprs(1, E);
13532 const Expr *OriginalE = Exprs.pop_back_val();
13540 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13541 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13544 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13545 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13546 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13548 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13549 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13550 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13551 Exprs.push_back(Temporary->getSubExpr());
13552 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13553 Exprs.push_back(Array->getIdx());
13554 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13555 Exprs.push_back(Compound->getInitializer());
13556 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13557 New &&
New->isArray()) {
13558 if (
auto ArraySize =
New->getArraySize())
13559 Exprs.push_back(*ArraySize);
13560 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13561 Exprs.push_back(MTE->getSubExpr());
13562 }
while (!Exprs.empty());
13570 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13577 class SequenceTree {
13579 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13580 unsigned Parent : 31;
13581 LLVM_PREFERRED_TYPE(
bool)
13582 unsigned Merged : 1;
13584 SmallVector<Value, 8> Values;
13590 friend class SequenceTree;
13594 explicit Seq(
unsigned N) : Index(N) {}
13597 Seq() : Index(0) {}
13600 SequenceTree() { Values.push_back(
Value(0)); }
13601 Seq root()
const {
return Seq(0); }
13606 Seq allocate(
Seq Parent) {
13607 Values.push_back(
Value(Parent.Index));
13608 return Seq(Values.size() - 1);
13612 void merge(
Seq S) {
13613 Values[S.Index].Merged =
true;
13619 bool isUnsequenced(
Seq Cur,
Seq Old) {
13620 unsigned C = representative(Cur.Index);
13621 unsigned Target = representative(Old.Index);
13625 C = Values[
C].Parent;
13632 unsigned representative(
unsigned K) {
13633 if (Values[K].Merged)
13635 return Values[K].Parent = representative(Values[K].Parent);
13641 using Object =
const NamedDecl *;
13655 UK_ModAsSideEffect,
13657 UK_Count = UK_ModAsSideEffect + 1
13663 const Expr *UsageExpr =
nullptr;
13664 SequenceTree::Seq
Seq;
13670 Usage Uses[UK_Count];
13673 bool Diagnosed =
false;
13677 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13685 UsageInfoMap UsageMap;
13688 SequenceTree::Seq Region;
13692 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13696 SmallVectorImpl<const Expr *> &WorkList;
13703 struct SequencedSubexpression {
13704 SequencedSubexpression(SequenceChecker &
Self)
13705 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13706 Self.ModAsSideEffect = &ModAsSideEffect;
13709 ~SequencedSubexpression() {
13710 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13714 UsageInfo &UI =
Self.UsageMap[M.first];
13715 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13716 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13717 SideEffectUsage = M.second;
13719 Self.ModAsSideEffect = OldModAsSideEffect;
13722 SequenceChecker &
Self;
13723 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13724 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13731 class EvaluationTracker {
13733 EvaluationTracker(SequenceChecker &
Self)
13735 Self.EvalTracker =
this;
13738 ~EvaluationTracker() {
13739 Self.EvalTracker = Prev;
13741 Prev->EvalOK &= EvalOK;
13744 bool evaluate(
const Expr *E,
bool &
Result) {
13749 Self.SemaRef.isConstantEvaluatedContext());
13754 SequenceChecker &
Self;
13755 EvaluationTracker *Prev;
13756 bool EvalOK =
true;
13757 } *EvalTracker =
nullptr;
13761 Object getObject(
const Expr *E,
bool Mod)
const {
13763 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
13764 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13765 return getObject(UO->getSubExpr(), Mod);
13766 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
13767 if (BO->getOpcode() == BO_Comma)
13768 return getObject(BO->getRHS(), Mod);
13769 if (Mod && BO->isAssignmentOp())
13770 return getObject(BO->getLHS(), Mod);
13771 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
13774 return ME->getMemberDecl();
13775 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
13784 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13786 Usage &U = UI.Uses[UK];
13787 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
13791 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
13792 ModAsSideEffect->push_back(std::make_pair(O, U));
13794 U.UsageExpr = UsageExpr;
13804 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
13805 UsageKind OtherKind,
bool IsModMod) {
13809 const Usage &U = UI.Uses[OtherKind];
13810 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
13813 const Expr *Mod = U.UsageExpr;
13814 const Expr *ModOrUse = UsageExpr;
13815 if (OtherKind == UK_Use)
13816 std::swap(Mod, ModOrUse);
13820 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
13821 : diag::warn_unsequenced_mod_use)
13822 << O << SourceRange(ModOrUse->
getExprLoc()));
13823 UI.Diagnosed =
true;
13852 void notePreUse(Object O,
const Expr *UseExpr) {
13853 UsageInfo &UI = UsageMap[O];
13855 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
13858 void notePostUse(Object O,
const Expr *UseExpr) {
13859 UsageInfo &UI = UsageMap[O];
13860 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
13862 addUsage(O, UI, UseExpr, UK_Use);
13865 void notePreMod(Object O,
const Expr *ModExpr) {
13866 UsageInfo &UI = UsageMap[O];
13868 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
13869 checkUsage(O, UI, ModExpr, UK_Use,
false);
13872 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
13873 UsageInfo &UI = UsageMap[O];
13874 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
13876 addUsage(O, UI, ModExpr, UK);
13880 SequenceChecker(Sema &S,
const Expr *E,
13881 SmallVectorImpl<const Expr *> &WorkList)
13882 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
13886 (void)this->WorkList;
13889 void VisitStmt(
const Stmt *S) {
13893 void VisitExpr(
const Expr *E) {
13895 Base::VisitStmt(E);
13898 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
13899 for (
auto *Sub : CSE->
children()) {
13900 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
13915 void VisitCastExpr(
const CastExpr *E) {
13927 void VisitSequencedExpressions(
const Expr *SequencedBefore,
13928 const Expr *SequencedAfter) {
13929 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
13930 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
13931 SequenceTree::Seq OldRegion = Region;
13934 SequencedSubexpression SeqBefore(*
this);
13935 Region = BeforeRegion;
13936 Visit(SequencedBefore);
13939 Region = AfterRegion;
13940 Visit(SequencedAfter);
13942 Region = OldRegion;
13944 Tree.merge(BeforeRegion);
13945 Tree.merge(AfterRegion);
13948 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
13953 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
13960 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13961 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13962 void VisitBinPtrMem(
const BinaryOperator *BO) {
13967 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13974 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13975 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13976 void VisitBinShlShr(
const BinaryOperator *BO) {
13980 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13987 void VisitBinComma(
const BinaryOperator *BO) {
13992 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13995 void VisitBinAssign(
const BinaryOperator *BO) {
13996 SequenceTree::Seq RHSRegion;
13997 SequenceTree::Seq LHSRegion;
13999 RHSRegion = Tree.allocate(Region);
14000 LHSRegion = Tree.allocate(Region);
14002 RHSRegion = Region;
14003 LHSRegion = Region;
14005 SequenceTree::Seq OldRegion = Region;
14021 SequencedSubexpression SeqBefore(*
this);
14022 Region = RHSRegion;
14026 Region = LHSRegion;
14030 notePostUse(O, BO);
14034 Region = LHSRegion;
14038 notePostUse(O, BO);
14040 Region = RHSRegion;
14048 Region = OldRegion;
14052 : UK_ModAsSideEffect);
14054 Tree.merge(RHSRegion);
14055 Tree.merge(LHSRegion);
14059 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14060 VisitBinAssign(CAO);
14063 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14064 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14065 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14068 return VisitExpr(UO);
14076 : UK_ModAsSideEffect);
14079 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14080 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14081 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14084 return VisitExpr(UO);
14088 notePostMod(O, UO, UK_ModAsSideEffect);
14091 void VisitBinLOr(
const BinaryOperator *BO) {
14097 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14098 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14099 SequenceTree::Seq OldRegion = Region;
14101 EvaluationTracker Eval(*
this);
14103 SequencedSubexpression Sequenced(*
this);
14104 Region = LHSRegion;
14111 bool EvalResult =
false;
14112 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14113 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14114 if (ShouldVisitRHS) {
14115 Region = RHSRegion;
14119 Region = OldRegion;
14120 Tree.merge(LHSRegion);
14121 Tree.merge(RHSRegion);
14124 void VisitBinLAnd(
const BinaryOperator *BO) {
14130 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14131 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14132 SequenceTree::Seq OldRegion = Region;
14134 EvaluationTracker Eval(*
this);
14136 SequencedSubexpression Sequenced(*
this);
14137 Region = LHSRegion;
14143 bool EvalResult =
false;
14144 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14145 bool ShouldVisitRHS = !EvalOK || EvalResult;
14146 if (ShouldVisitRHS) {
14147 Region = RHSRegion;
14151 Region = OldRegion;
14152 Tree.merge(LHSRegion);
14153 Tree.merge(RHSRegion);
14156 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14161 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14177 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14178 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14179 SequenceTree::Seq OldRegion = Region;
14181 EvaluationTracker Eval(*
this);
14183 SequencedSubexpression Sequenced(*
this);
14184 Region = ConditionRegion;
14194 bool EvalResult =
false;
14195 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14196 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14197 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14198 if (ShouldVisitTrueExpr) {
14199 Region = TrueRegion;
14202 if (ShouldVisitFalseExpr) {
14203 Region = FalseRegion;
14207 Region = OldRegion;
14208 Tree.merge(ConditionRegion);
14209 Tree.merge(TrueRegion);
14210 Tree.merge(FalseRegion);
14213 void VisitCallExpr(
const CallExpr *CE) {
14225 SequencedSubexpression Sequenced(*
this);
14230 SequenceTree::Seq CalleeRegion;
14231 SequenceTree::Seq OtherRegion;
14232 if (SemaRef.getLangOpts().CPlusPlus17) {
14233 CalleeRegion = Tree.allocate(Region);
14234 OtherRegion = Tree.allocate(Region);
14236 CalleeRegion = Region;
14237 OtherRegion = Region;
14239 SequenceTree::Seq OldRegion = Region;
14242 Region = CalleeRegion;
14244 SequencedSubexpression Sequenced(*this);
14245 Visit(CE->getCallee());
14247 Visit(CE->getCallee());
14251 Region = OtherRegion;
14255 Region = OldRegion;
14257 Tree.merge(CalleeRegion);
14258 Tree.merge(OtherRegion);
14276 return VisitCallExpr(CXXOCE);
14287 case OO_MinusEqual:
14289 case OO_SlashEqual:
14290 case OO_PercentEqual:
14291 case OO_CaretEqual:
14294 case OO_LessLessEqual:
14295 case OO_GreaterGreaterEqual:
14296 SequencingKind = RHSBeforeLHS;
14300 case OO_GreaterGreater:
14306 SequencingKind = LHSBeforeRHS;
14310 SequencingKind = LHSBeforeRest;
14314 SequencingKind = NoSequencing;
14318 if (SequencingKind == NoSequencing)
14319 return VisitCallExpr(CXXOCE);
14322 SequencedSubexpression Sequenced(*
this);
14325 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14326 "Should only get there with C++17 and above!");
14327 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14328 "Should only get there with an overloaded binary operator"
14329 " or an overloaded call operator!");
14331 if (SequencingKind == LHSBeforeRest) {
14332 assert(CXXOCE->getOperator() == OO_Call &&
14333 "We should only have an overloaded call operator here!");
14342 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14343 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14344 SequenceTree::Seq OldRegion = Region;
14346 assert(CXXOCE->getNumArgs() >= 1 &&
14347 "An overloaded call operator must have at least one argument"
14348 " for the postfix-expression!");
14349 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14350 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14351 CXXOCE->getNumArgs() - 1);
14355 Region = PostfixExprRegion;
14356 SequencedSubexpression Sequenced(*this);
14357 Visit(PostfixExpr);
14361 Region = ArgsRegion;
14362 for (const Expr *Arg : Args)
14365 Region = OldRegion;
14366 Tree.merge(PostfixExprRegion);
14367 Tree.merge(ArgsRegion);
14369 assert(CXXOCE->getNumArgs() == 2 &&
14370 "Should only have two arguments here!");
14371 assert((SequencingKind == LHSBeforeRHS ||
14372 SequencingKind == RHSBeforeLHS) &&
14373 "Unexpected sequencing kind!");
14377 const Expr *E1 = CXXOCE->getArg(0);
14378 const Expr *E2 = CXXOCE->getArg(1);
14379 if (SequencingKind == RHSBeforeLHS)
14382 return VisitSequencedExpressions(E1, E2);
14389 SequencedSubexpression Sequenced(*
this);
14392 return VisitExpr(CCE);
14395 SequenceExpressionsInOrder(
14401 return VisitExpr(ILE);
14404 SequenceExpressionsInOrder(ILE->
inits());
14416 SequenceTree::Seq Parent = Region;
14417 for (
const Expr *E : ExpressionList) {
14420 Region = Tree.allocate(Parent);
14421 Elts.push_back(Region);
14427 for (
unsigned I = 0; I < Elts.size(); ++I)
14428 Tree.merge(Elts[I]);
14432SequenceChecker::UsageInfo::UsageInfo() =
default;
14436void Sema::CheckUnsequencedOperations(
const Expr *E) {
14437 SmallVector<const Expr *, 8> WorkList;
14438 WorkList.push_back(E);
14439 while (!WorkList.empty()) {
14440 const Expr *Item = WorkList.pop_back_val();
14441 SequenceChecker(*
this, Item, WorkList);
14446 bool IsConstexpr) {
14449 CheckImplicitConversions(E, CheckLoc);
14451 CheckUnsequencedOperations(E);
14453 CheckForIntOverflow(E);
14466 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14470 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14474 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14488 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14492 bool CheckParameterNames) {
14493 bool HasInvalidParm =
false;
14495 assert(Param &&
"null in a parameter list");
14504 if (!Param->isInvalidDecl() &&
14506 diag::err_typecheck_decl_incomplete_type) ||
14508 diag::err_abstract_type_in_decl,
14510 Param->setInvalidDecl();
14511 HasInvalidParm =
true;
14516 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14520 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14528 QualType PType = Param->getOriginalType();
14536 if (!Param->isInvalidDecl()) {
14537 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14538 if (!ClassDecl->isInvalidDecl() &&
14539 !ClassDecl->hasIrrelevantDestructor() &&
14540 !ClassDecl->isDependentContext() &&
14541 ClassDecl->isParamDestroyedInCallee()) {
14553 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14554 if (!Param->getType().isConstQualified())
14555 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14559 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14564 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14565 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14570 if (!Param->isInvalidDecl() &&
14571 Param->getOriginalType()->isWebAssemblyTableType()) {
14572 Param->setInvalidDecl();
14573 HasInvalidParm =
true;
14574 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14578 return HasInvalidParm;
14581std::optional<std::pair<
14590static std::pair<CharUnits, CharUnits>
14598 if (
Base->isVirtual()) {
14605 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14612 DerivedType =
Base->getType();
14615 return std::make_pair(BaseAlignment, Offset);
14619static std::optional<std::pair<CharUnits, CharUnits>>
14625 return std::nullopt;
14630 return std::nullopt;
14634 CharUnits Offset = EltSize * IdxRes->getExtValue();
14637 return std::make_pair(P->first, P->second + Offset);
14643 return std::make_pair(
14644 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14650std::optional<std::pair<
14658 case Stmt::CStyleCastExprClass:
14659 case Stmt::CXXStaticCastExprClass:
14660 case Stmt::ImplicitCastExprClass: {
14662 const Expr *From = CE->getSubExpr();
14663 switch (CE->getCastKind()) {
14668 case CK_UncheckedDerivedToBase:
14669 case CK_DerivedToBase: {
14679 case Stmt::ArraySubscriptExprClass: {
14684 case Stmt::DeclRefExprClass: {
14688 if (!VD->getType()->isReferenceType()) {
14690 if (VD->hasDependentAlignment())
14699 case Stmt::MemberExprClass: {
14701 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14705 std::optional<std::pair<CharUnits, CharUnits>> P;
14714 return std::make_pair(P->first,
14717 case Stmt::UnaryOperatorClass: {
14727 case Stmt::BinaryOperatorClass: {
14739 return std::nullopt;
14744std::optional<std::pair<
14753 case Stmt::CStyleCastExprClass:
14754 case Stmt::CXXStaticCastExprClass:
14755 case Stmt::ImplicitCastExprClass: {
14757 const Expr *From = CE->getSubExpr();
14758 switch (CE->getCastKind()) {
14763 case CK_ArrayToPointerDecay:
14765 case CK_UncheckedDerivedToBase:
14766 case CK_DerivedToBase: {
14776 case Stmt::CXXThisExprClass: {
14781 case Stmt::UnaryOperatorClass: {
14787 case Stmt::BinaryOperatorClass: {
14796 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
14797 std::swap(LHS, RHS);
14807 return std::nullopt;
14812 std::optional<std::pair<CharUnits, CharUnits>> P =
14816 return P->first.alignmentAtOffset(P->second);
14834 if (!DestPtr)
return;
14840 if (DestAlign.
isOne())
return;
14844 if (!SrcPtr)
return;
14855 if (SrcAlign >= DestAlign)
return;
14860 <<
static_cast<unsigned>(DestAlign.
getQuantity())
14864void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
14866 bool AllowOnePastEnd,
bool IndexNegated) {
14875 const Type *EffectiveType =
14879 Context.getAsConstantArrayType(BaseExpr->
getType());
14882 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
14884 const Type *BaseType =
14886 bool IsUnboundedArray =
14888 Context, StrictFlexArraysLevel,
14891 (!IsUnboundedArray && BaseType->isDependentType()))
14899 if (IndexNegated) {
14900 index.setIsUnsigned(
false);
14904 if (IsUnboundedArray) {
14907 if (
index.isUnsigned() || !
index.isNegative()) {
14909 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
14911 if (
index.getBitWidth() < AddrBits)
14913 std::optional<CharUnits> ElemCharUnits =
14914 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14917 if (!ElemCharUnits || ElemCharUnits->isZero())
14919 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
14924 if (
index.getActiveBits() <= AddrBits) {
14926 llvm::APInt Product(
index);
14928 Product = Product.umul_ov(ElemBytes, Overflow);
14929 if (!Overflow && Product.getActiveBits() <= AddrBits)
14935 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
14936 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
14938 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
14939 MaxElems = MaxElems.udiv(ElemBytes);
14942 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
14943 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
14948 PDiag(DiagID) << index << AddrBits
14949 << (
unsigned)ASTC.toBits(*ElemCharUnits)
14950 << ElemBytes << MaxElems
14951 << MaxElems.getZExtValue()
14954 const NamedDecl *ND =
nullptr;
14956 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14958 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14960 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14961 ND = ME->getMemberDecl();
14965 PDiag(diag::note_array_declared_here) << ND);
14970 if (index.isUnsigned() || !index.isNegative()) {
14980 llvm::APInt size = ArrayTy->
getSize();
14982 if (BaseType != EffectiveType) {
14990 if (!ptrarith_typesize)
14991 ptrarith_typesize =
Context.getCharWidth();
14993 if (ptrarith_typesize != array_typesize) {
14995 uint64_t ratio = array_typesize / ptrarith_typesize;
14999 if (ptrarith_typesize * ratio == array_typesize)
15000 size *= llvm::APInt(size.getBitWidth(), ratio);
15004 if (size.getBitWidth() > index.getBitWidth())
15005 index = index.zext(size.getBitWidth());
15006 else if (size.getBitWidth() < index.getBitWidth())
15007 size = size.zext(index.getBitWidth());
15013 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15020 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15022 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15023 SourceLocation IndexLoc =
15025 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15030 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15031 : diag::warn_ptr_arith_exceeds_bounds;
15032 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15033 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15037 << index << ArrayTy->
desugar() << CastMsg
15040 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15042 DiagID = diag::warn_ptr_arith_precedes_bounds;
15043 if (index.isNegative()) index = -index;
15050 const NamedDecl *ND =
nullptr;
15052 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15054 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15056 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15057 ND = ME->getMemberDecl();
15061 PDiag(diag::note_array_declared_here) << ND);
15064void Sema::CheckArrayAccess(
const Expr *
expr) {
15065 int AllowOnePastEnd = 0;
15067 expr =
expr->IgnoreParenImpCasts();
15068 switch (
expr->getStmtClass()) {
15069 case Stmt::ArraySubscriptExprClass: {
15072 AllowOnePastEnd > 0);
15076 case Stmt::MemberExprClass: {
15080 case Stmt::ArraySectionExprClass: {
15086 nullptr, AllowOnePastEnd > 0);
15089 case Stmt::UnaryOperatorClass: {
15105 case Stmt::ConditionalOperatorClass: {
15107 if (
const Expr *lhs = cond->
getLHS())
15108 CheckArrayAccess(lhs);
15109 if (
const Expr *rhs = cond->
getRHS())
15110 CheckArrayAccess(rhs);
15113 case Stmt::CXXOperatorCallExprClass: {
15115 for (
const auto *Arg : OCE->arguments())
15116 CheckArrayAccess(Arg);
15126 Expr *RHS,
bool isProperty) {
15138 S.
Diag(Loc, diag::warn_arc_literal_assign)
15140 << (isProperty ? 0 : 1)
15148 Expr *RHS,
bool isProperty) {
15151 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15152 S.
Diag(Loc, diag::warn_arc_retained_assign)
15154 << (isProperty ? 0 : 1)
15158 RHS =
cast->getSubExpr();
15200 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15229 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15230 Diag(Loc, diag::warn_arc_retained_property_assign)
15234 RHS =
cast->getSubExpr();
15257 bool StmtLineInvalid;
15258 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15260 if (StmtLineInvalid)
15263 bool BodyLineInvalid;
15264 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15266 if (BodyLineInvalid)
15270 if (StmtLine != BodyLine)
15285 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15294 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15298 const Stmt *PossibleBody) {
15304 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15305 StmtLoc = FS->getRParenLoc();
15306 Body = FS->getBody();
15307 DiagID = diag::warn_empty_for_body;
15308 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15309 StmtLoc = WS->getRParenLoc();
15310 Body = WS->getBody();
15311 DiagID = diag::warn_empty_while_body;
15316 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15340 if (!ProbableTypo) {
15341 bool BodyColInvalid;
15342 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15344 if (BodyColInvalid)
15347 bool StmtColInvalid;
15350 if (StmtColInvalid)
15353 if (BodyCol > StmtCol)
15354 ProbableTypo =
true;
15357 if (ProbableTypo) {
15359 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15367 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15379 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15381 RHSExpr = CE->
getArg(0);
15382 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15383 CXXSCE && CXXSCE->isXValue())
15384 RHSExpr = CXXSCE->getSubExpr();
15388 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15389 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15392 if (LHSDeclRef && RHSDeclRef) {
15399 auto D =
Diag(OpLoc, diag::warn_self_move)
15415 const Expr *LHSBase = LHSExpr;
15416 const Expr *RHSBase = RHSExpr;
15417 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15418 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15419 if (!LHSME || !RHSME)
15422 while (LHSME && RHSME) {
15429 LHSME = dyn_cast<MemberExpr>(LHSBase);
15430 RHSME = dyn_cast<MemberExpr>(RHSBase);
15433 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15434 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15435 if (LHSDeclRef && RHSDeclRef) {
15442 Diag(OpLoc, diag::warn_self_move)
15449 Diag(OpLoc, diag::warn_self_move)
15473 bool AreUnionMembers =
false) {
15477 assert(((Field1Parent->isStructureOrClassType() &&
15478 Field2Parent->isStructureOrClassType()) ||
15479 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15480 "Can't evaluate layout compatibility between a struct field and a "
15482 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15483 (AreUnionMembers && Field1Parent->isUnionType())) &&
15484 "AreUnionMembers should be 'true' for union fields (only).");
15498 if (Bits1 != Bits2)
15502 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15503 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15506 if (!AreUnionMembers &&
15518 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15519 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15521 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15522 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15527 return isLayoutCompatible(C, F1, F2);
15538 for (
auto *Field1 : RD1->
fields()) {
15539 auto I = UnmatchedFields.begin();
15540 auto E = UnmatchedFields.end();
15542 for ( ; I != E; ++I) {
15544 bool Result = UnmatchedFields.erase(*I);
15554 return UnmatchedFields.empty();
15580 if (
C.hasSameType(T1, T2))
15589 if (TC1 == Type::Enum)
15591 if (TC1 == Type::Record) {
15610 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15641 const ValueDecl **VD, uint64_t *MagicValue,
15642 bool isConstantEvaluated) {
15650 case Stmt::UnaryOperatorClass: {
15659 case Stmt::DeclRefExprClass: {
15665 case Stmt::IntegerLiteralClass: {
15667 llvm::APInt MagicValueAPInt = IL->
getValue();
15668 if (MagicValueAPInt.getActiveBits() <= 64) {
15669 *MagicValue = MagicValueAPInt.getZExtValue();
15675 case Stmt::BinaryConditionalOperatorClass:
15676 case Stmt::ConditionalOperatorClass: {
15681 isConstantEvaluated)) {
15691 case Stmt::BinaryOperatorClass: {
15694 TypeExpr = BO->
getRHS();
15724 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15727 bool isConstantEvaluated) {
15728 FoundWrongKind =
false;
15733 uint64_t MagicValue;
15735 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15739 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15740 if (I->getArgumentKind() != ArgumentKind) {
15741 FoundWrongKind =
true;
15744 TypeInfo.Type = I->getMatchingCType();
15745 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15746 TypeInfo.MustBeNull = I->getMustBeNull();
15757 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15758 if (I == MagicValues->end())
15767 bool LayoutCompatible,
15769 if (!TypeTagForDatatypeMagicValues)
15770 TypeTagForDatatypeMagicValues.reset(
15771 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15774 (*TypeTagForDatatypeMagicValues)[Magic] =
15790 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
15791 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
15792 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
15793 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
15796void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
15799 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
15800 bool IsPointerAttr = Attr->getIsPointer();
15803 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
15804 if (TypeTagIdxAST >= ExprArgs.size()) {
15805 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15806 << 0 << Attr->getTypeTagIdx().getSourceIndex();
15809 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
15810 bool FoundWrongKind;
15813 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
15815 if (FoundWrongKind)
15817 diag::warn_type_tag_for_datatype_wrong_kind)
15823 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
15824 if (ArgumentIdxAST >= ExprArgs.size()) {
15825 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15826 << 1 << Attr->getArgumentIdx().getSourceIndex();
15829 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
15830 if (IsPointerAttr) {
15832 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
15833 if (ICE->getType()->isVoidPointerType() &&
15834 ICE->getCastKind() == CK_BitCast)
15835 ArgumentExpr = ICE->getSubExpr();
15837 QualType ArgumentType = ArgumentExpr->
getType();
15843 if (TypeInfo.MustBeNull) {
15848 diag::warn_type_safety_null_pointer_required)
15856 QualType RequiredType = TypeInfo.Type;
15858 RequiredType =
Context.getPointerType(RequiredType);
15860 bool mismatch =
false;
15861 if (!TypeInfo.LayoutCompatible) {
15862 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
15883 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
15884 << ArgumentType << ArgumentKind
15885 << TypeInfo.LayoutCompatible << RequiredType
15903 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
15911 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
15917 auto &MisalignedMembersForExpr =
15919 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
15920 if (MA != MisalignedMembersForExpr.end() &&
15921 (
T->isDependentType() ||
T->isIntegerType() ||
15922 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
15924 T->getPointeeType()) <= MA->Alignment))))
15925 MisalignedMembersForExpr.erase(MA);
15934 const auto *ME = dyn_cast<MemberExpr>(E);
15946 bool AnyIsPacked =
false;
15948 QualType BaseType = ME->getBase()->getType();
15949 if (BaseType->isDependentType())
15953 auto *RD = BaseType->castAsRecordDecl();
15958 auto *FD = dyn_cast<FieldDecl>(MD);
15964 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
15965 ReverseMemberChain.push_back(FD);
15968 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
15970 assert(TopME &&
"We did not compute a topmost MemberExpr!");
15977 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
15988 if (ExpectedAlignment.
isOne())
15993 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
15994 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
15998 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16002 if (DRE && !TopME->
isArrow()) {
16005 CompleteObjectAlignment =
16006 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16010 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16013 CompleteObjectAlignment < ExpectedAlignment) {
16024 for (
FieldDecl *FDI : ReverseMemberChain) {
16025 if (FDI->hasAttr<PackedAttr>() ||
16026 FDI->getParent()->hasAttr<PackedAttr>()) {
16028 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16034 assert(FD &&
"We did not find a packed FieldDecl!");
16035 Action(E, FD->
getParent(), FD, Alignment);
16039void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16040 using namespace std::placeholders;
16043 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16067bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16068 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16081 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
16082 TheCall->
setType(VecTy0->getElementType());
16095 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16112 assert(!Args.empty() &&
"Should have at least one argument.");
16114 Expr *Arg0 = Args.front();
16117 auto EmitError = [&](
Expr *ArgI) {
16119 diag::err_typecheck_call_different_arg_types)
16120 << Arg0->
getType() << ArgI->getType();
16125 for (
Expr *ArgI : Args.drop_front())
16136 for (
Expr *ArgI : Args.drop_front()) {
16137 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16140 VecI->getElementType()) ||
16141 Vec0->getNumElements() != VecI->getNumElements()) {
16150std::optional<QualType>
16154 return std::nullopt;
16158 return std::nullopt;
16161 for (
int I = 0; I < 2; ++I) {
16165 return std::nullopt;
16166 Args[I] = Converted.
get();
16173 return std::nullopt;
16176 return std::nullopt;
16178 TheCall->
setArg(0, Args[0]);
16179 TheCall->
setArg(1, Args[1]);
16190 TheCall->
getArg(1), Loc) ||
16192 TheCall->
getArg(2), Loc))
16196 for (
int I = 0; I < 3; ++I) {
16201 Args[I] = Converted.
get();
16204 int ArgOrdinal = 1;
16205 for (
Expr *Arg : Args) {
16207 ArgTyRestr, ArgOrdinal++))
16214 for (
int I = 0; I < 3; ++I)
16215 TheCall->
setArg(I, Args[I]);
16221bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16233bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16242 diag::err_builtin_invalid_arg_type)
16243 << 1 << 2 << 1 << 1 << TyArg;
16257 Expr *Matrix = MatrixArg.
get();
16259 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16262 << 1 << 3 << 0 << 0
16269 QualType ResultType =
Context.getConstantMatrixType(
16270 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16273 TheCall->
setType(ResultType);
16276 TheCall->
setArg(0, Matrix);
16281static std::optional<unsigned>
16289 uint64_t
Dim =
Value->getZExtValue();
16308 unsigned PtrArgIdx = 0;
16309 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16310 Expr *RowsExpr = TheCall->
getArg(1);
16311 Expr *ColumnsExpr = TheCall->
getArg(2);
16312 Expr *StrideExpr = TheCall->
getArg(3);
16314 bool ArgError =
false;
16321 PtrExpr = PtrConv.
get();
16322 TheCall->
setArg(0, PtrExpr);
16329 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16330 QualType ElementTy;
16333 << PtrArgIdx + 1 << 0 << 5 << 0
16337 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16341 << PtrArgIdx + 1 << 0 << 5
16348 auto ApplyArgumentConversions = [
this](Expr *E) {
16357 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16359 RowsExpr = RowsConv.
get();
16360 TheCall->
setArg(1, RowsExpr);
16362 RowsExpr =
nullptr;
16364 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16366 ColumnsExpr = ColumnsConv.
get();
16367 TheCall->
setArg(2, ColumnsExpr);
16369 ColumnsExpr =
nullptr;
16380 std::optional<unsigned> MaybeRows;
16384 std::optional<unsigned> MaybeColumns;
16389 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16392 StrideExpr = StrideConv.
get();
16393 TheCall->
setArg(3, StrideExpr);
16396 if (std::optional<llvm::APSInt>
Value =
16399 if (Stride < *MaybeRows) {
16401 diag::err_builtin_matrix_stride_too_small);
16407 if (ArgError || !MaybeRows || !MaybeColumns)
16411 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16420 unsigned PtrArgIdx = 1;
16421 Expr *MatrixExpr = TheCall->
getArg(0);
16422 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16423 Expr *StrideExpr = TheCall->
getArg(2);
16425 bool ArgError =
false;
16431 MatrixExpr = MatrixConv.
get();
16432 TheCall->
setArg(0, MatrixExpr);
16439 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16442 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16450 PtrExpr = PtrConv.
get();
16451 TheCall->
setArg(1, PtrExpr);
16459 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16462 << PtrArgIdx + 1 << 0 << 5 << 0
16466 QualType ElementTy = PtrTy->getPointeeType();
16468 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16473 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16475 diag::err_builtin_matrix_pointer_arg_mismatch)
16476 << ElementTy << MatrixTy->getElementType();
16491 StrideExpr = StrideConv.
get();
16492 TheCall->
setArg(2, StrideExpr);
16497 if (std::optional<llvm::APSInt>
Value =
16500 if (Stride < MatrixTy->getNumRows()) {
16502 diag::err_builtin_matrix_stride_too_small);
16522 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16527 llvm::StringSet<> CalleeTCBs;
16528 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16529 CalleeTCBs.insert(A->getTCBName());
16530 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16531 CalleeTCBs.insert(A->getTCBName());
16535 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16536 StringRef CallerTCB = A->getTCBName();
16537 if (CalleeTCBs.count(CallerTCB) == 0) {
16538 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16539 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
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
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)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
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 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 bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
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 ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
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 void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
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 CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static ExprResult BuiltinTriviallyRelocate(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 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 void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
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 const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
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 bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
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 ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
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 ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
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::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 std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static bool IsEnumConstOrFromMacro(Sema &S, const Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall)
static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC)
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 bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static void CheckCommaOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl< AnalyzeImplicitConversionsWorkItem > &WorkList)
static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static int classifyConstantValue(Expr *Constant)
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 llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool PruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
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 ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall)
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call)
static bool requiresParensToAddCast(const Expr *E)
static bool HasEnumType(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
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 const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
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 CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos, bool AllowConst, bool AllowAS)
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 checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
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 ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall)
static bool ConvertMaskedBuiltinArgs(Sema &S, CallExpr *TheCall)
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 checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)
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::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 bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for DirectX constructs.
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 SPIRV 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.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
MatchKind
How well a given conversion specifier matches its argument.
@ NoMatch
The conversion specifier and the argument types are incompatible.
@ NoMatchPedantic
The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...
@ Match
The conversion specifier and the argument type are compatible.
@ MatchPromotion
The conversion specifier and the argument type are compatible because of default argument promotions.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
@ NoMatchTypeConfusion
The conversion specifier and the argument type are compatible, but still seems likely to be an error.
@ NoMatchPromotionTypeConfusion
The conversion specifier and the argument type are compatible but still seems likely to be an error.
unsigned getLength() const
const char * toString() const
const char * getStart() const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantAmount() const
unsigned getConstantLength() const
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
Changes the specifier and length according to a QualType, retaining any flags or options.
void toString(raw_ostream &os) const
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
void toString(raw_ostream &os) const
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
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 LangOptions & getLangOpts() const
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.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
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 getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
CanQualType UnsignedLongLongTy
CanQualType UnsignedShortTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
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...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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 ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
SourceLocation getQuestionLoc() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
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,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
static bool isAdditiveOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
BinaryOperatorKind Opcode
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
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.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool isDynamicClass() 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 * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getEndLoc() const
SourceLocation getRParenLoc() const
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...
void shrinkNumArgs(unsigned NewNumArgs)
Reduce the number of arguments in this call expression.
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.
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.
ConditionalOperator - The ?
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.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
static ConvertVectorExpr * Create(const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc, FPOptionsOverride FPFeatures)
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.
bool isStdNamespace() const
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.
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 getBeginLoc() const
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
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
std::string getAsString() const
Retrieve the human-readable string for this name.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
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.
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.
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.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
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...
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.
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 isFlexibleArrayMemberLike(const 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 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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
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.
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.
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
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.
const ParmVarDecl * getParamDecl(unsigned i) const
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
ArrayRef< ParmVarDecl * > parameters() 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.
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.
Represents a prototype with parameter type info, e.g.
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.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
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.
UnresolvedSetImpl::iterator iterator
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.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
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.
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.
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.
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.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
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)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
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.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
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()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
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.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
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.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ 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 checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
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...
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.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
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...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
FPOptionsOverride CurFPFeatureOverrides()
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)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
DiagnosticsEngine & getDiagnostics() const
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)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
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 isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
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 BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() 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 RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
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.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
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
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
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
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.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
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 PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
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())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
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.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
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.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
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.
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.
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
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
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.
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 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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
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...
RecordDecl * castAsRecordDecl() const
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,...
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
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.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
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.
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
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
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 ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
std::string getRepresentativeTypeName(ASTContext &C) const
MatchKind matchesType(ASTContext &C, QualType argTy) const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantLength() const
const char * toString() const
const char * getPosition() const
const OptionalFlag & isPrivate() const
bool hasValidLeftJustified() const
bool hasValidFieldWidth() const
bool hasValidSpacePrefix() const
const OptionalAmount & getPrecision() const
const OptionalFlag & hasSpacePrefix() const
bool usesPositionalArg() const
const OptionalFlag & isSensitive() const
const OptionalFlag & isLeftJustified() const
bool hasValidPrecision() const
const OptionalFlag & hasLeadingZeros() const
const OptionalFlag & hasAlternativeForm() const
bool hasValidLeadingZeros() const
void toString(raw_ostream &os) const
const PrintfConversionSpecifier & getConversionSpecifier() const
const OptionalFlag & hasPlusPrefix() const
const OptionalFlag & hasThousandsGrouping() const
bool hasValidThousandsGroupingPrefix() const
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have.
const OptionalFlag & isPublic() const
bool consumesDataArgument() const
bool hasValidPlusPrefix() const
bool hasValidAlternativeForm() const
bool consumesDataArgument() const
const ScanfConversionSpecifier & getConversionSpecifier() const
ArgType getArgType(ASTContext &Ctx) const
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
Pieces specific to fprintf format strings.
Pieces specific to fscanf format strings.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
uint32_t Literal
Literals are represented as positive integers.
ComparisonResult
Indicates the result of a tentative comparison.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ 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 LT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool hasSpecificAttr(const Container &container)
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ Success
Annotation was successful.
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.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
MutableArrayRef< Expr * > MultiExprArg
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
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())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
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
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.
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.
SmallVector< MisalignedMember, 4 > MisalignedMembers
Small set of gathered accesses to potentially misaligned members due to the packed attribute.