83#include "llvm/ADT/APFloat.h"
84#include "llvm/ADT/APInt.h"
85#include "llvm/ADT/APSInt.h"
86#include "llvm/ADT/ArrayRef.h"
87#include "llvm/ADT/DenseMap.h"
88#include "llvm/ADT/FoldingSet.h"
89#include "llvm/ADT/STLExtras.h"
90#include "llvm/ADT/STLForwardCompat.h"
91#include "llvm/ADT/SmallBitVector.h"
92#include "llvm/ADT/SmallPtrSet.h"
93#include "llvm/ADT/SmallString.h"
94#include "llvm/ADT/SmallVector.h"
95#include "llvm/ADT/StringExtras.h"
96#include "llvm/ADT/StringRef.h"
97#include "llvm/ADT/StringSet.h"
98#include "llvm/ADT/StringSwitch.h"
99#include "llvm/Support/AtomicOrdering.h"
100#include "llvm/Support/Compiler.h"
101#include "llvm/Support/ConvertUTF.h"
102#include "llvm/Support/ErrorHandling.h"
103#include "llvm/Support/Format.h"
104#include "llvm/Support/Locale.h"
105#include "llvm/Support/MathExtras.h"
106#include "llvm/Support/SaveAndRestore.h"
107#include "llvm/Support/raw_ostream.h"
108#include "llvm/TargetParser/RISCVTargetParser.h"
109#include "llvm/TargetParser/Triple.h"
122using namespace clang;
126 unsigned ByteNo)
const {
137 unsigned ArgCount =
Call->getNumArgs();
138 if (ArgCount >= MinArgCount)
141 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
142 << 0 << MinArgCount << ArgCount
143 << 0 <<
Call->getSourceRange();
147 unsigned ArgCount =
Call->getNumArgs();
148 if (ArgCount <= MaxArgCount)
150 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
151 << 0 << MaxArgCount << ArgCount
152 << 0 <<
Call->getSourceRange();
156 unsigned MaxArgCount) {
162 unsigned ArgCount =
Call->getNumArgs();
163 if (ArgCount == DesiredArgCount)
168 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
172 Call->getArg(ArgCount - 1)->getEndLoc());
174 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
175 << 0 << DesiredArgCount << ArgCount
180 bool HasError =
false;
182 for (
const Expr *Arg :
Call->arguments()) {
183 if (Arg->isValueDependent())
186 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
187 int DiagMsgKind = -1;
189 if (!ArgString.has_value())
191 else if (ArgString->find(
'$') != std::string::npos)
194 if (DiagMsgKind >= 0) {
195 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
196 << DiagMsgKind << Arg->getSourceRange();
205 if (
Value->isTypeDependent())
236 if (!Literal || !Literal->isOrdinary()) {
249 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
257 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
258 if (!Literal || !Literal->isWide()) {
259 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
260 << Arg->getSourceRange();
297 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
328 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
330 auto IsValidIntegerType = [](
QualType Ty) {
331 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
338 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
340 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
343 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_type);
345 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_member_pointer);
347 S.
Diag(Source->getExprLoc(),
348 diag::note_alignment_invalid_function_pointer);
353 if (!IsValidIntegerType(AlignOp->
getType())) {
364 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
365 llvm::APSInt MaxValue(
366 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
367 if (AlignValue < 1) {
368 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
371 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
376 if (!AlignValue.isPowerOf2()) {
377 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
380 if (AlignValue == 1) {
381 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
382 << IsBooleanAlignBuiltin;
410 std::pair<unsigned, const char *> Builtins[] = {
411 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
412 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
413 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
416 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
423 auto ValidCkdIntType = [](
QualType QT) {
426 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
427 return (BT->getKind() >= BuiltinType::Short &&
428 BT->getKind() <= BuiltinType::Int128) || (
429 BT->getKind() >= BuiltinType::UShort &&
430 BT->getKind() <= BuiltinType::UInt128) ||
431 BT->getKind() == BuiltinType::UChar ||
432 BT->getKind() == BuiltinType::SChar;
437 for (
unsigned I = 0; I < 2; ++I) {
443 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
462 !PtrTy->getPointeeType()->isIntegerType() ||
463 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
464 PtrTy->getPointeeType().isConstQualified()) {
466 diag::err_overflow_builtin_must_be_ptr_int)
474 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
475 for (
unsigned I = 0; I < 3; ++I) {
476 const auto Arg = TheCall->
getArg(I);
479 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
481 return S.
Diag(Arg->getBeginLoc(),
482 diag::err_overflow_builtin_bit_int_max_size)
491struct BuiltinDumpStructGenerator {
495 SmallVector<Expr *, 32> Actions;
496 DiagnosticErrorTrap ErrorTracker;
497 PrintingPolicy Policy;
499 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
500 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
501 Policy(S.Context.getPrintingPolicy()) {
503 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
506 Expr *makeOpaqueValueExpr(Expr *Inner) {
510 Actions.push_back(OVE);
514 Expr *getStringLiteral(llvm::StringRef Str) {
517 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
520 bool callPrintFunction(llvm::StringRef Format,
521 llvm::ArrayRef<Expr *> Exprs = {}) {
522 SmallVector<Expr *, 8> Args;
524 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
526 Args.push_back(getStringLiteral(Format));
527 llvm::append_range(Args, Exprs);
530 Sema::CodeSynthesisContext Ctx;
543 Actions.push_back(RealCall.
get());
549 Expr *getIndentString(
unsigned Depth) {
553 llvm::SmallString<32>
Indent;
555 return getStringLiteral(
Indent);
562 bool appendFormatSpecifier(QualType T, llvm::SmallVectorImpl<char> &Str) {
563 llvm::raw_svector_ostream
OS(Str);
567 if (
auto *BT = T->
getAs<BuiltinType>()) {
568 switch (BT->getKind()) {
569 case BuiltinType::Bool:
572 case BuiltinType::Char_U:
573 case BuiltinType::UChar:
576 case BuiltinType::Char_S:
577 case BuiltinType::SChar:
585 analyze_printf::PrintfSpecifier
Specifier;
588 if (
Specifier.getConversionSpecifier().getKind() ==
589 analyze_printf::PrintfConversionSpecifier::sArg) {
595 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
615 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
616 Expr *IndentLit = getIndentString(Depth);
618 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
619 : callPrintFunction(
"%s", {TypeLit}))
622 return dumpRecordValue(RD, E, IndentLit, Depth);
626 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
635 Expr *RecordArg = makeOpaqueValueExpr(E);
638 if (callPrintFunction(
" {\n"))
642 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
643 for (
const auto &Base : CXXRD->bases()) {
651 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
657 Expr *FieldIndentArg = getIndentString(Depth + 1);
660 for (
auto *D : RD->
decls()) {
661 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
662 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
663 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
666 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
667 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
669 getStringLiteral(FD->getName())};
671 if (FD->isBitField()) {
675 FD->getBitWidthValue());
683 CXXScopeSpec(), Loc, IFD,
686 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
688 DeclarationNameInfo(FD->getDeclName(), Loc));
689 if (
Field.isInvalid())
692 auto *InnerRD = FD->getType()->getAsRecordDecl();
693 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
694 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
696 if (callPrintFunction(Format, Args) ||
697 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
701 if (appendFormatSpecifier(FD->getType(), Format)) {
703 Args.push_back(
Field.get());
713 Args.push_back(FieldAddr.
get());
716 if (callPrintFunction(Format, Args))
721 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
722 : callPrintFunction(
"}\n");
725 Expr *buildWrapper() {
728 TheCall->
setType(Wrapper->getType());
749 diag::err_expected_struct_pointer_argument)
758 diag::err_incomplete_type))
767 switch (BT ? BT->getKind() : BuiltinType::Void) {
768 case BuiltinType::Dependent:
769 case BuiltinType::Overload:
770 case BuiltinType::BoundMember:
771 case BuiltinType::PseudoObject:
772 case BuiltinType::UnknownAny:
773 case BuiltinType::BuiltinFn:
779 diag::err_expected_callable_argument)
785 BuiltinDumpStructGenerator Generator(S, TheCall);
791 Expr *PtrArg = PtrArgResult.
get();
795 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
798 return Generator.buildWrapper();
810 if (
Call->getStmtClass() != Stmt::CallExprClass) {
811 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
812 <<
Call->getSourceRange();
817 if (CE->getCallee()->getType()->isBlockPointerType()) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
819 <<
Call->getSourceRange();
823 const Decl *TargetDecl = CE->getCalleeDecl();
824 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
825 if (FD->getBuiltinID()) {
826 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
827 <<
Call->getSourceRange();
832 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
833 <<
Call->getSourceRange();
841 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
855 BuiltinCall->
setType(CE->getType());
859 BuiltinCall->
setArg(1, ChainResult.
get());
866class ScanfDiagnosticFormatHandler
870 using ComputeSizeFunction =
871 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
875 using DiagnoseFunction =
876 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
878 ComputeSizeFunction ComputeSizeArgument;
879 DiagnoseFunction Diagnose;
882 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
883 DiagnoseFunction Diagnose)
884 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
886 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
887 const char *StartSpecifier,
888 unsigned specifierLen)
override {
892 unsigned NulByte = 0;
904 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
906 analyze_format_string::OptionalAmount::HowSpecified::Constant)
911 std::optional<llvm::APSInt> DestSizeAPS =
916 unsigned DestSize = DestSizeAPS->getZExtValue();
918 if (DestSize < SourceSize)
925class EstimateSizeFormatHandler
930 bool IsKernelCompatible =
true;
933 EstimateSizeFormatHandler(StringRef Format)
934 :
Size(std::
min(Format.find(0), Format.size()) +
937 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
938 const char *,
unsigned SpecifierLen,
939 const TargetInfo &)
override {
941 const size_t FieldWidth = computeFieldWidth(FS);
942 const size_t Precision = computePrecision(FS);
949 Size += std::max(FieldWidth, (
size_t)1);
961 Size += std::max(FieldWidth, Precision);
977 Size += std::max(FieldWidth, 1 +
978 (Precision ? 1 + Precision
988 (Precision ? 1 + Precision : 0) +
998 (Precision ? 1 + Precision : 0) +
1013 IsKernelCompatible =
false;
1014 Size += std::max(FieldWidth, 2 + Precision);
1061 Size += (Precision ? 0 : 1);
1068 assert(SpecifierLen <= Size &&
"no underflow");
1069 Size -= SpecifierLen;
1073 size_t getSizeLowerBound()
const {
return Size; }
1074 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1077 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1078 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1079 size_t FieldWidth = 0;
1085 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1086 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1087 size_t Precision = 0;
1134 StringRef &FormatStrRef,
size_t &StrLen,
1136 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1137 Format && (Format->isOrdinary() || Format->isUTF8())) {
1138 FormatStrRef = Format->getString();
1140 Context.getAsConstantArrayType(Format->getType());
1141 assert(T &&
"String literal not of constant array type!");
1142 size_t TypeSize = T->getZExtSize();
1144 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1150void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1156 bool UseDABAttr =
false;
1157 const FunctionDecl *UseDecl = FD;
1159 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1161 UseDecl = DABAttr->getFunction();
1162 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1174 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1181 unsigned DABIndices = DABAttr->argIndices_size();
1182 unsigned NewIndex = Index < DABIndices
1183 ? DABAttr->argIndices_begin()[Index]
1186 return std::nullopt;
1190 auto ComputeExplicitObjectSizeArgument =
1191 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1192 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1194 return std::nullopt;
1195 unsigned NewIndex = *IndexOptional;
1197 Expr *SizeArg = TheCall->
getArg(NewIndex);
1199 return std::nullopt;
1205 auto ComputeSizeArgument =
1206 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1212 if (Index < FD->getNumParams()) {
1213 if (
const auto *POS =
1215 BOSType = POS->getType();
1218 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1220 return std::nullopt;
1221 unsigned NewIndex = *IndexOptional;
1224 return std::nullopt;
1226 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1227 if (std::optional<uint64_t> ObjSize =
1230 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1232 return std::nullopt;
1235 auto ComputeStrLenArgument =
1236 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1237 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1239 return std::nullopt;
1240 unsigned NewIndex = *IndexOptional;
1242 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1244 if (std::optional<uint64_t>
Result =
1247 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1249 return std::nullopt;
1252 std::optional<llvm::APSInt> SourceSize;
1253 std::optional<llvm::APSInt> DestinationSize;
1254 unsigned DiagID = 0;
1255 bool IsChkVariant =
false;
1257 auto GetFunctionName = [&]() {
1258 std::string FunctionNameStr =
1260 llvm::StringRef FunctionName = FunctionNameStr;
1265 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1266 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1268 FunctionName.consume_front(
"__builtin_");
1270 return FunctionName.str();
1273 switch (BuiltinID) {
1276 case Builtin::BI__builtin_strcat:
1277 case Builtin::BIstrcat:
1278 case Builtin::BI__builtin_stpcpy:
1279 case Builtin::BIstpcpy:
1280 case Builtin::BI__builtin_strcpy:
1281 case Builtin::BIstrcpy: {
1282 DiagID = diag::warn_fortify_strlen_overflow;
1283 SourceSize = ComputeStrLenArgument(1);
1284 DestinationSize = ComputeSizeArgument(0);
1288 case Builtin::BI__builtin___strcat_chk:
1289 case Builtin::BI__builtin___stpcpy_chk:
1290 case Builtin::BI__builtin___strcpy_chk: {
1291 DiagID = diag::warn_fortify_strlen_overflow;
1292 SourceSize = ComputeStrLenArgument(1);
1293 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1294 IsChkVariant =
true;
1298 case Builtin::BIscanf:
1299 case Builtin::BIfscanf:
1300 case Builtin::BIsscanf: {
1301 unsigned FormatIndex = 1;
1302 unsigned DataIndex = 2;
1303 if (BuiltinID == Builtin::BIscanf) {
1308 const auto *FormatExpr =
1311 StringRef FormatStrRef;
1316 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1317 unsigned SourceSize) {
1318 DiagID = diag::warn_fortify_scanf_overflow;
1319 unsigned Index = ArgIndex + DataIndex;
1320 std::string FunctionName = GetFunctionName();
1322 PDiag(DiagID) << FunctionName << (Index + 1)
1323 << DestSize << SourceSize);
1326 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1327 return ComputeSizeArgument(Index + DataIndex);
1329 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1330 const char *FormatBytes = FormatStrRef.data();
1341 case Builtin::BIsprintf:
1342 case Builtin::BI__builtin___sprintf_chk: {
1343 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1346 StringRef FormatStrRef;
1349 EstimateSizeFormatHandler H(FormatStrRef);
1350 const char *FormatBytes = FormatStrRef.data();
1352 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1353 Context.getTargetInfo(),
false)) {
1354 DiagID = H.isKernelCompatible()
1355 ? diag::warn_format_overflow
1356 : diag::warn_format_overflow_non_kprintf;
1357 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1358 .extOrTrunc(SizeTypeWidth);
1359 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1360 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1361 IsChkVariant =
true;
1363 DestinationSize = ComputeSizeArgument(0);
1370 case Builtin::BI__builtin___memcpy_chk:
1371 case Builtin::BI__builtin___memmove_chk:
1372 case Builtin::BI__builtin___memset_chk:
1373 case Builtin::BI__builtin___strlcat_chk:
1374 case Builtin::BI__builtin___strlcpy_chk:
1375 case Builtin::BI__builtin___strncat_chk:
1376 case Builtin::BI__builtin___strncpy_chk:
1377 case Builtin::BI__builtin___stpncpy_chk:
1378 case Builtin::BI__builtin___memccpy_chk:
1379 case Builtin::BI__builtin___mempcpy_chk: {
1380 DiagID = diag::warn_builtin_chk_overflow;
1381 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1383 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1384 IsChkVariant =
true;
1388 case Builtin::BI__builtin___snprintf_chk:
1389 case Builtin::BI__builtin___vsnprintf_chk: {
1390 DiagID = diag::warn_builtin_chk_overflow;
1391 SourceSize = ComputeExplicitObjectSizeArgument(1);
1392 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1393 IsChkVariant =
true;
1397 case Builtin::BIstrncat:
1398 case Builtin::BI__builtin_strncat:
1399 case Builtin::BIstrncpy:
1400 case Builtin::BI__builtin_strncpy:
1401 case Builtin::BIstpncpy:
1402 case Builtin::BI__builtin_stpncpy: {
1408 DiagID = diag::warn_fortify_source_size_mismatch;
1409 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1410 DestinationSize = ComputeSizeArgument(0);
1414 case Builtin::BIbzero:
1415 case Builtin::BI__builtin_bzero:
1416 case Builtin::BImemcpy:
1417 case Builtin::BI__builtin_memcpy:
1418 case Builtin::BImemmove:
1419 case Builtin::BI__builtin_memmove:
1420 case Builtin::BImemset:
1421 case Builtin::BI__builtin_memset:
1422 case Builtin::BImempcpy:
1423 case Builtin::BI__builtin_mempcpy: {
1424 DiagID = diag::warn_fortify_source_overflow;
1425 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1426 DestinationSize = ComputeSizeArgument(0);
1429 case Builtin::BIbcopy:
1430 case Builtin::BI__builtin_bcopy: {
1431 DiagID = diag::warn_fortify_source_overflow;
1432 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1433 DestinationSize = ComputeSizeArgument(1);
1436 case Builtin::BIsnprintf:
1437 case Builtin::BI__builtin_snprintf:
1438 case Builtin::BIvsnprintf:
1439 case Builtin::BI__builtin_vsnprintf: {
1440 DiagID = diag::warn_fortify_source_size_mismatch;
1441 SourceSize = ComputeExplicitObjectSizeArgument(1);
1443 StringRef FormatStrRef;
1447 EstimateSizeFormatHandler H(FormatStrRef);
1448 const char *FormatBytes = FormatStrRef.data();
1450 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1451 Context.getTargetInfo(),
false)) {
1452 llvm::APSInt FormatSize =
1453 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1454 .extOrTrunc(SizeTypeWidth);
1455 if (FormatSize > *SourceSize && *SourceSize != 0) {
1456 unsigned TruncationDiagID =
1457 H.isKernelCompatible() ? diag::warn_format_truncation
1458 : diag::warn_format_truncation_non_kprintf;
1459 SmallString<16> SpecifiedSizeStr;
1460 SmallString<16> FormatSizeStr;
1461 SourceSize->toString(SpecifiedSizeStr, 10);
1462 FormatSize.toString(FormatSizeStr, 10);
1464 PDiag(TruncationDiagID)
1465 << GetFunctionName() << SpecifiedSizeStr
1470 DestinationSize = ComputeSizeArgument(0);
1474 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1478 if (!SourceSize || !DestinationSize ||
1479 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1482 std::string FunctionName = GetFunctionName();
1484 SmallString<16> DestinationStr;
1485 SmallString<16> SourceStr;
1486 DestinationSize->toString(DestinationStr, 10);
1487 SourceSize->toString(SourceStr, 10);
1490 << FunctionName << DestinationStr << SourceStr);
1505 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1508 << DRE->getDecl()->getIdentifier();
1520 "__builtin_alloca has invalid address space");
1533 if (Arg->isTypeDependent() || Arg->isValueDependent())
1536 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1538 return S.
Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1546enum PointerAuthOpKind {
1561 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1592 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1595 llvm::raw_svector_ostream Str(
Value);
1604 Result = KeyValue->getZExtValue();
1623 bool IsAddrDiscArg =
false;
1628 IsAddrDiscArg =
true;
1637 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1638 <<
Result->getExtValue();
1640 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1646 IntVal =
Result->getZExtValue();
1650static std::pair<const ValueDecl *, CharUnits>
1657 const auto *BaseDecl =
1662 return {BaseDecl,
Result.Val.getLValueOffset()};
1666 bool RequireConstant =
false) {
1674 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1675 return OpKind != PAO_BlendInteger;
1677 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1678 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1679 OpKind == PAO_SignGeneric;
1688 }
else if (AllowsInteger(OpKind) &&
1695 <<
unsigned(OpKind == PAO_Discriminator ? 1
1696 : OpKind == PAO_BlendPointer ? 2
1697 : OpKind == PAO_BlendInteger ? 3
1699 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1709 if (!RequireConstant) {
1711 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1714 ? diag::warn_ptrauth_sign_null_pointer
1715 : diag::warn_ptrauth_auth_null_pointer)
1725 if (OpKind == PAO_Sign) {
1743 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1748 assert(OpKind == PAO_Discriminator);
1754 if (
Call->getBuiltinCallee() ==
1755 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1770 assert(
Pointer->getType()->isPointerType());
1782 assert(
Integer->getType()->isIntegerType());
1788 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1801 Call->setType(
Call->getArgs()[0]->getType());
1832 PointerAuthOpKind OpKind,
1833 bool RequireConstant) {
1844 Call->setType(
Call->getArgs()[0]->getType());
1860 Call->setType(
Call->getArgs()[0]->getType());
1869 const Expr *AddendExpr =
Call->getArg(5);
1871 if (!AddendIsConstInt) {
1872 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
1886 Call->setType(
Call->getArgs()[0]->getType());
1895 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1898 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1899 if (!Literal || Literal->getCharByteWidth() != 1) {
1915 Call->setArg(0, FirstValue.
get());
1921 if (!FirstArgRecord) {
1922 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1923 << 0 << FirstArgType;
1928 diag::err_get_vtable_pointer_requires_complete_type)) {
1933 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1934 << 1 << FirstArgRecord;
1938 Call->setType(ReturnType);
1963 auto DiagSelect = [&]() -> std::optional<unsigned> {
1970 return std::optional<unsigned>{};
1985 diag::err_incomplete_type))
1989 "Unhandled non-object pointer case");
2017 if (PT->getPointeeType()->isFunctionType()) {
2019 diag::err_builtin_is_within_lifetime_invalid_arg)
2025 if (PT->getPointeeType()->isVariableArrayType()) {
2027 << 1 <<
"__builtin_is_within_lifetime";
2032 diag::err_builtin_is_within_lifetime_invalid_arg)
2046 diag::err_builtin_trivially_relocate_invalid_arg_type)
2053 diag::err_incomplete_type))
2057 T->isIncompleteArrayType()) {
2059 diag::err_builtin_trivially_relocate_invalid_arg_type)
2060 << (T.isConstQualified() ? 1 : 2);
2069 diag::err_builtin_trivially_relocate_invalid_arg_type)
2076 if (Size.isInvalid())
2080 if (Size.isInvalid())
2082 SizeExpr = Size.get();
2083 TheCall->
setArg(2, SizeExpr);
2093 llvm::Triple::ObjectFormatType CurObjFormat =
2095 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2108 llvm::Triple::ArchType CurArch =
2110 if (llvm::is_contained(SupportedArchs, CurArch))
2120bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2127 case llvm::Triple::arm:
2128 case llvm::Triple::armeb:
2129 case llvm::Triple::thumb:
2130 case llvm::Triple::thumbeb:
2132 case llvm::Triple::aarch64:
2133 case llvm::Triple::aarch64_32:
2134 case llvm::Triple::aarch64_be:
2136 case llvm::Triple::bpfeb:
2137 case llvm::Triple::bpfel:
2139 case llvm::Triple::dxil:
2141 case llvm::Triple::hexagon:
2143 case llvm::Triple::mips:
2144 case llvm::Triple::mipsel:
2145 case llvm::Triple::mips64:
2146 case llvm::Triple::mips64el:
2148 case llvm::Triple::spirv:
2149 case llvm::Triple::spirv32:
2150 case llvm::Triple::spirv64:
2151 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2154 case llvm::Triple::systemz:
2156 case llvm::Triple::x86:
2157 case llvm::Triple::x86_64:
2159 case llvm::Triple::ppc:
2160 case llvm::Triple::ppcle:
2161 case llvm::Triple::ppc64:
2162 case llvm::Triple::ppc64le:
2164 case llvm::Triple::amdgcn:
2166 case llvm::Triple::riscv32:
2167 case llvm::Triple::riscv64:
2168 case llvm::Triple::riscv32be:
2169 case llvm::Triple::riscv64be:
2171 case llvm::Triple::loongarch32:
2172 case llvm::Triple::loongarch64:
2175 case llvm::Triple::wasm32:
2176 case llvm::Triple::wasm64:
2178 case llvm::Triple::nvptx:
2179 case llvm::Triple::nvptx64:
2185 return T->isDependentType() ||
2186 (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
2201 switch (ArgTyRestr) {
2204 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2205 << ArgOrdinal << 2 << 1 << 1
2212 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2213 << ArgOrdinal << 5 << 0
2219 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2220 << ArgOrdinal << 5 << 1
2226 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2240 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2241 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2242 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2243 "Expecting __builtin_cpu_...");
2245 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2247 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2248 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2249 (!IsCPUSupports && TInfo->supportsCpuIs()));
2251 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2258 ? diag::err_builtin_aix_os_unsupported
2259 : diag::err_builtin_target_unsupported)
2265 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2303 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2304 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2305 BT->getNumBits() != 1) {
2307 << ArgTy << BT->getNumBits();
2383 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2386 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2395 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2396 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2416 TheCall->
setArg(0, Arg0);
2433 TheCall->
setArg(1, Arg1);
2439 << 2 << 1 << 4 << 0 << Arg1Ty;
2453 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2455 << (OnlyUnsigned ? 3 : 1)
2463 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2466 return OnlyUnsigned ? T->isUnsignedIntegerType() : T->isIntegerType();
2471 return emitError(S, Loc, T);
2476 return emitError(S, Loc, T);
2482 return emitError(S, Loc, T);
2487 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2492 return emitError(S, Loc, T);
2497 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2503 llvm_unreachable(
"conversion functions are permitted");
2522 TheCall->
setArg(0, Arg0);
2536 TheCall->
setArg(1, Arg1);
2547 unsigned Pos,
bool AllowConst,
2551 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2556 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2557 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2558 << Pos <<
"scalar pointer";
2567 diag::err_typecheck_convert_incompatible)
2576 bool TypeDependent =
false;
2577 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2605 Builtin::BI__builtin_masked_load))
2619 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2642 Builtin::BI__builtin_masked_store))
2650 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2661 << MaskTy << ValTy);
2665 PtrTy->getPointeeType().getUnqualifiedType()))
2667 diag::err_vec_builtin_incompatible_vector)
2696 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2709 << MaskTy << IdxTy);
2718 diag::err_vec_masked_load_store_ptr)
2747 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2762 << MaskTy << IdxTy);
2768 << MaskTy << ValTy);
2771 PtrTy->getPointeeType().getUnqualifiedType()))
2773 diag::err_vec_builtin_incompatible_vector)
2787 if (Args.size() == 0) {
2789 diag::err_typecheck_call_too_few_args_at_least)
2795 QualType FuncT = Args[0]->getType();
2798 if (Args.size() < 2) {
2800 diag::err_typecheck_call_too_few_args_at_least)
2806 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2807 QualType ObjectT = Args[1]->getType();
2809 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2858 tok::periodstar, ObjectArg.
get(), Args[0]);
2862 if (MPT->isMemberDataPointer())
2865 auto *MemCall =
new (S.
Context)
2889 return TyA->getElementType();
2896Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2901 unsigned ICEArguments = 0;
2903 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2908 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2910 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2915 if (ArgNo < TheCall->getNumArgs() &&
2918 ICEArguments &= ~(1 << ArgNo);
2922 switch (BuiltinID) {
2923 case Builtin::BI__builtin_cpu_supports:
2924 case Builtin::BI__builtin_cpu_is:
2926 Context.getAuxTargetInfo(), BuiltinID))
2929 case Builtin::BI__builtin_cpu_init:
2930 if (!
Context.getTargetInfo().supportsCpuInit()) {
2936 case Builtin::BI__builtin___CFStringMakeConstantString:
2940 *
this, BuiltinID, TheCall,
2941 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2944 "Wrong # arguments to builtin CFStringMakeConstantString");
2945 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2948 case Builtin::BI__builtin_ms_va_start:
2949 case Builtin::BI__builtin_stdarg_start:
2950 case Builtin::BI__builtin_va_start:
2951 case Builtin::BI__builtin_c23_va_start:
2952 if (BuiltinVAStart(BuiltinID, TheCall))
2955 case Builtin::BI__va_start: {
2956 switch (
Context.getTargetInfo().getTriple().getArch()) {
2957 case llvm::Triple::aarch64:
2958 case llvm::Triple::arm:
2959 case llvm::Triple::thumb:
2960 if (BuiltinVAStartARMMicrosoft(TheCall))
2964 if (BuiltinVAStart(BuiltinID, TheCall))
2972 case Builtin::BI_interlockedbittestandset_acq:
2973 case Builtin::BI_interlockedbittestandset_rel:
2974 case Builtin::BI_interlockedbittestandset_nf:
2975 case Builtin::BI_interlockedbittestandreset_acq:
2976 case Builtin::BI_interlockedbittestandreset_rel:
2977 case Builtin::BI_interlockedbittestandreset_nf:
2980 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2985 case Builtin::BI_bittest64:
2986 case Builtin::BI_bittestandcomplement64:
2987 case Builtin::BI_bittestandreset64:
2988 case Builtin::BI_bittestandset64:
2989 case Builtin::BI_interlockedbittestandreset64:
2990 case Builtin::BI_interlockedbittestandset64:
2993 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2994 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2999 case Builtin::BI_interlockedbittestandreset64_acq:
3000 case Builtin::BI_interlockedbittestandreset64_rel:
3001 case Builtin::BI_interlockedbittestandreset64_nf:
3002 case Builtin::BI_interlockedbittestandset64_acq:
3003 case Builtin::BI_interlockedbittestandset64_rel:
3004 case Builtin::BI_interlockedbittestandset64_nf:
3009 case Builtin::BI__builtin_set_flt_rounds:
3012 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3013 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
3014 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3015 llvm::Triple::ppc64le}))
3019 case Builtin::BI__builtin_isgreater:
3020 case Builtin::BI__builtin_isgreaterequal:
3021 case Builtin::BI__builtin_isless:
3022 case Builtin::BI__builtin_islessequal:
3023 case Builtin::BI__builtin_islessgreater:
3024 case Builtin::BI__builtin_isunordered:
3025 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3028 case Builtin::BI__builtin_fpclassify:
3029 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3032 case Builtin::BI__builtin_isfpclass:
3033 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3036 case Builtin::BI__builtin_isfinite:
3037 case Builtin::BI__builtin_isinf:
3038 case Builtin::BI__builtin_isinf_sign:
3039 case Builtin::BI__builtin_isnan:
3040 case Builtin::BI__builtin_issignaling:
3041 case Builtin::BI__builtin_isnormal:
3042 case Builtin::BI__builtin_issubnormal:
3043 case Builtin::BI__builtin_iszero:
3044 case Builtin::BI__builtin_signbit:
3045 case Builtin::BI__builtin_signbitf:
3046 case Builtin::BI__builtin_signbitl:
3047 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3050 case Builtin::BI__builtin_shufflevector:
3054 case Builtin::BI__builtin_masked_load:
3055 case Builtin::BI__builtin_masked_expand_load:
3057 case Builtin::BI__builtin_masked_store:
3058 case Builtin::BI__builtin_masked_compress_store:
3060 case Builtin::BI__builtin_masked_gather:
3062 case Builtin::BI__builtin_masked_scatter:
3064 case Builtin::BI__builtin_invoke:
3066 case Builtin::BI__builtin_prefetch:
3067 if (BuiltinPrefetch(TheCall))
3070 case Builtin::BI__builtin_alloca_with_align:
3071 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3072 if (BuiltinAllocaWithAlign(TheCall))
3075 case Builtin::BI__builtin_alloca:
3076 case Builtin::BI__builtin_alloca_uninitialized:
3083 case Builtin::BI__builtin_infer_alloc_token:
3087 case Builtin::BI__arithmetic_fence:
3088 if (BuiltinArithmeticFence(TheCall))
3091 case Builtin::BI__assume:
3092 case Builtin::BI__builtin_assume:
3093 if (BuiltinAssume(TheCall))
3096 case Builtin::BI__builtin_assume_aligned:
3097 if (BuiltinAssumeAligned(TheCall))
3100 case Builtin::BI__builtin_dynamic_object_size:
3101 case Builtin::BI__builtin_object_size:
3105 case Builtin::BI__builtin_longjmp:
3106 if (BuiltinLongjmp(TheCall))
3109 case Builtin::BI__builtin_setjmp:
3110 if (BuiltinSetjmp(TheCall))
3113 case Builtin::BI__builtin_complex:
3114 if (BuiltinComplex(TheCall))
3117 case Builtin::BI__builtin_classify_type:
3118 case Builtin::BI__builtin_constant_p: {
3127 case Builtin::BI__builtin_launder:
3129 case Builtin::BI__builtin_is_within_lifetime:
3131 case Builtin::BI__builtin_trivially_relocate:
3133 case Builtin::BI__builtin_clear_padding: {
3137 const Expr *PtrArg = TheCall->
getArg(0);
3138 const QualType PtrArgType = PtrArg->
getType();
3141 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3152 diag::err_typecheck_decl_incomplete_type))
3158 auto IsAddrOfDeclExpr = [&]() {
3160 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3161 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3165 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3166 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3170 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3171 if (!VarDecl || VarDecl->getType()->isReferenceType())
3176 QualType VarQType = VarDecl->getType();
3178 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3183 && !IsAddrOfDeclExpr()) {
3184 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3191 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3198 case Builtin::BI__sync_fetch_and_add:
3199 case Builtin::BI__sync_fetch_and_add_1:
3200 case Builtin::BI__sync_fetch_and_add_2:
3201 case Builtin::BI__sync_fetch_and_add_4:
3202 case Builtin::BI__sync_fetch_and_add_8:
3203 case Builtin::BI__sync_fetch_and_add_16:
3204 case Builtin::BI__sync_fetch_and_sub:
3205 case Builtin::BI__sync_fetch_and_sub_1:
3206 case Builtin::BI__sync_fetch_and_sub_2:
3207 case Builtin::BI__sync_fetch_and_sub_4:
3208 case Builtin::BI__sync_fetch_and_sub_8:
3209 case Builtin::BI__sync_fetch_and_sub_16:
3210 case Builtin::BI__sync_fetch_and_or:
3211 case Builtin::BI__sync_fetch_and_or_1:
3212 case Builtin::BI__sync_fetch_and_or_2:
3213 case Builtin::BI__sync_fetch_and_or_4:
3214 case Builtin::BI__sync_fetch_and_or_8:
3215 case Builtin::BI__sync_fetch_and_or_16:
3216 case Builtin::BI__sync_fetch_and_and:
3217 case Builtin::BI__sync_fetch_and_and_1:
3218 case Builtin::BI__sync_fetch_and_and_2:
3219 case Builtin::BI__sync_fetch_and_and_4:
3220 case Builtin::BI__sync_fetch_and_and_8:
3221 case Builtin::BI__sync_fetch_and_and_16:
3222 case Builtin::BI__sync_fetch_and_xor:
3223 case Builtin::BI__sync_fetch_and_xor_1:
3224 case Builtin::BI__sync_fetch_and_xor_2:
3225 case Builtin::BI__sync_fetch_and_xor_4:
3226 case Builtin::BI__sync_fetch_and_xor_8:
3227 case Builtin::BI__sync_fetch_and_xor_16:
3228 case Builtin::BI__sync_fetch_and_nand:
3229 case Builtin::BI__sync_fetch_and_nand_1:
3230 case Builtin::BI__sync_fetch_and_nand_2:
3231 case Builtin::BI__sync_fetch_and_nand_4:
3232 case Builtin::BI__sync_fetch_and_nand_8:
3233 case Builtin::BI__sync_fetch_and_nand_16:
3234 case Builtin::BI__sync_add_and_fetch:
3235 case Builtin::BI__sync_add_and_fetch_1:
3236 case Builtin::BI__sync_add_and_fetch_2:
3237 case Builtin::BI__sync_add_and_fetch_4:
3238 case Builtin::BI__sync_add_and_fetch_8:
3239 case Builtin::BI__sync_add_and_fetch_16:
3240 case Builtin::BI__sync_sub_and_fetch:
3241 case Builtin::BI__sync_sub_and_fetch_1:
3242 case Builtin::BI__sync_sub_and_fetch_2:
3243 case Builtin::BI__sync_sub_and_fetch_4:
3244 case Builtin::BI__sync_sub_and_fetch_8:
3245 case Builtin::BI__sync_sub_and_fetch_16:
3246 case Builtin::BI__sync_and_and_fetch:
3247 case Builtin::BI__sync_and_and_fetch_1:
3248 case Builtin::BI__sync_and_and_fetch_2:
3249 case Builtin::BI__sync_and_and_fetch_4:
3250 case Builtin::BI__sync_and_and_fetch_8:
3251 case Builtin::BI__sync_and_and_fetch_16:
3252 case Builtin::BI__sync_or_and_fetch:
3253 case Builtin::BI__sync_or_and_fetch_1:
3254 case Builtin::BI__sync_or_and_fetch_2:
3255 case Builtin::BI__sync_or_and_fetch_4:
3256 case Builtin::BI__sync_or_and_fetch_8:
3257 case Builtin::BI__sync_or_and_fetch_16:
3258 case Builtin::BI__sync_xor_and_fetch:
3259 case Builtin::BI__sync_xor_and_fetch_1:
3260 case Builtin::BI__sync_xor_and_fetch_2:
3261 case Builtin::BI__sync_xor_and_fetch_4:
3262 case Builtin::BI__sync_xor_and_fetch_8:
3263 case Builtin::BI__sync_xor_and_fetch_16:
3264 case Builtin::BI__sync_nand_and_fetch:
3265 case Builtin::BI__sync_nand_and_fetch_1:
3266 case Builtin::BI__sync_nand_and_fetch_2:
3267 case Builtin::BI__sync_nand_and_fetch_4:
3268 case Builtin::BI__sync_nand_and_fetch_8:
3269 case Builtin::BI__sync_nand_and_fetch_16:
3270 case Builtin::BI__sync_val_compare_and_swap:
3271 case Builtin::BI__sync_val_compare_and_swap_1:
3272 case Builtin::BI__sync_val_compare_and_swap_2:
3273 case Builtin::BI__sync_val_compare_and_swap_4:
3274 case Builtin::BI__sync_val_compare_and_swap_8:
3275 case Builtin::BI__sync_val_compare_and_swap_16:
3276 case Builtin::BI__sync_bool_compare_and_swap:
3277 case Builtin::BI__sync_bool_compare_and_swap_1:
3278 case Builtin::BI__sync_bool_compare_and_swap_2:
3279 case Builtin::BI__sync_bool_compare_and_swap_4:
3280 case Builtin::BI__sync_bool_compare_and_swap_8:
3281 case Builtin::BI__sync_bool_compare_and_swap_16:
3282 case Builtin::BI__sync_lock_test_and_set:
3283 case Builtin::BI__sync_lock_test_and_set_1:
3284 case Builtin::BI__sync_lock_test_and_set_2:
3285 case Builtin::BI__sync_lock_test_and_set_4:
3286 case Builtin::BI__sync_lock_test_and_set_8:
3287 case Builtin::BI__sync_lock_test_and_set_16:
3288 case Builtin::BI__sync_lock_release:
3289 case Builtin::BI__sync_lock_release_1:
3290 case Builtin::BI__sync_lock_release_2:
3291 case Builtin::BI__sync_lock_release_4:
3292 case Builtin::BI__sync_lock_release_8:
3293 case Builtin::BI__sync_lock_release_16:
3294 case Builtin::BI__sync_swap:
3295 case Builtin::BI__sync_swap_1:
3296 case Builtin::BI__sync_swap_2:
3297 case Builtin::BI__sync_swap_4:
3298 case Builtin::BI__sync_swap_8:
3299 case Builtin::BI__sync_swap_16:
3300 return BuiltinAtomicOverloaded(TheCallResult);
3301 case Builtin::BI__sync_synchronize:
3305 case Builtin::BI__builtin_nontemporal_load:
3306 case Builtin::BI__builtin_nontemporal_store:
3307 return BuiltinNontemporalOverloaded(TheCallResult);
3308 case Builtin::BI__builtin_memcpy_inline: {
3309 clang::Expr *SizeOp = TheCall->
getArg(2);
3321 case Builtin::BI__builtin_memset_inline: {
3322 clang::Expr *SizeOp = TheCall->
getArg(2);
3332#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3333 case Builtin::BI##ID: \
3334 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3335#include "clang/Basic/Builtins.inc"
3336 case Builtin::BI__annotation: {
3337 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3338 if (!TT.isOSWindows() && !TT.isUEFI()) {
3347 case Builtin::BI__builtin_annotation:
3351 case Builtin::BI__builtin_addressof:
3355 case Builtin::BI__builtin_function_start:
3359 case Builtin::BI__builtin_is_aligned:
3360 case Builtin::BI__builtin_align_up:
3361 case Builtin::BI__builtin_align_down:
3365 case Builtin::BI__builtin_add_overflow:
3366 case Builtin::BI__builtin_sub_overflow:
3367 case Builtin::BI__builtin_mul_overflow:
3371 case Builtin::BI__builtin_operator_new:
3372 case Builtin::BI__builtin_operator_delete: {
3373 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3375 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3378 case Builtin::BI__builtin_dump_struct:
3380 case Builtin::BI__builtin_expect_with_probability: {
3385 const Expr *ProbArg = TheCall->
getArg(2);
3386 SmallVector<PartialDiagnosticAt, 8> Notes;
3387 Expr::EvalResult Eval;
3391 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3398 bool LoseInfo =
false;
3399 Probability.convert(llvm::APFloat::IEEEdouble(),
3400 llvm::RoundingMode::Dynamic, &LoseInfo);
3401 if (!(Probability >= llvm::APFloat(0.0) &&
3402 Probability <= llvm::APFloat(1.0))) {
3409 case Builtin::BI__builtin_preserve_access_index:
3413 case Builtin::BI__builtin_call_with_static_chain:
3417 case Builtin::BI__exception_code:
3418 case Builtin::BI_exception_code:
3420 diag::err_seh___except_block))
3423 case Builtin::BI__exception_info:
3424 case Builtin::BI_exception_info:
3426 diag::err_seh___except_filter))
3429 case Builtin::BI__GetExceptionInfo:
3441 case Builtin::BIaddressof:
3442 case Builtin::BI__addressof:
3443 case Builtin::BIforward:
3444 case Builtin::BIforward_like:
3445 case Builtin::BImove:
3446 case Builtin::BImove_if_noexcept:
3447 case Builtin::BIas_const: {
3455 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3456 BuiltinID == Builtin::BI__addressof;
3458 (ReturnsPointer ?
Result->isAnyPointerType()
3459 :
Result->isReferenceType()) &&
3462 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3468 case Builtin::BI__builtin_ptrauth_strip:
3470 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3472 case Builtin::BI__builtin_ptrauth_sign_constant:
3475 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3478 case Builtin::BI__builtin_ptrauth_auth:
3481 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3483 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3485 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3487 case Builtin::BI__builtin_ptrauth_string_discriminator:
3490 case Builtin::BI__builtin_get_vtable_pointer:
3494 case Builtin::BIread_pipe:
3495 case Builtin::BIwrite_pipe:
3498 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3501 case Builtin::BIreserve_read_pipe:
3502 case Builtin::BIreserve_write_pipe:
3503 case Builtin::BIwork_group_reserve_read_pipe:
3504 case Builtin::BIwork_group_reserve_write_pipe:
3505 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3508 case Builtin::BIsub_group_reserve_read_pipe:
3509 case Builtin::BIsub_group_reserve_write_pipe:
3510 if (
OpenCL().checkSubgroupExt(TheCall) ||
3511 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3514 case Builtin::BIcommit_read_pipe:
3515 case Builtin::BIcommit_write_pipe:
3516 case Builtin::BIwork_group_commit_read_pipe:
3517 case Builtin::BIwork_group_commit_write_pipe:
3518 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3521 case Builtin::BIsub_group_commit_read_pipe:
3522 case Builtin::BIsub_group_commit_write_pipe:
3523 if (
OpenCL().checkSubgroupExt(TheCall) ||
3524 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3527 case Builtin::BIget_pipe_num_packets:
3528 case Builtin::BIget_pipe_max_packets:
3529 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3532 case Builtin::BIto_global:
3533 case Builtin::BIto_local:
3534 case Builtin::BIto_private:
3535 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3539 case Builtin::BIenqueue_kernel:
3540 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3543 case Builtin::BIget_kernel_work_group_size:
3544 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3545 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3548 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3549 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3550 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3553 case Builtin::BI__builtin_os_log_format:
3554 Cleanup.setExprNeedsCleanups(
true);
3556 case Builtin::BI__builtin_os_log_format_buffer_size:
3557 if (BuiltinOSLogFormat(TheCall))
3560 case Builtin::BI__builtin_frame_address:
3561 case Builtin::BI__builtin_return_address: {
3570 Result.Val.getInt() != 0)
3572 << ((BuiltinID == Builtin::BI__builtin_return_address)
3573 ?
"__builtin_return_address"
3574 :
"__builtin_frame_address")
3579 case Builtin::BI__builtin_nondeterministic_value: {
3580 if (BuiltinNonDeterministicValue(TheCall))
3587 case Builtin::BI__builtin_elementwise_abs:
3595 case Builtin::BI__builtin_elementwise_acos:
3596 case Builtin::BI__builtin_elementwise_asin:
3597 case Builtin::BI__builtin_elementwise_atan:
3598 case Builtin::BI__builtin_elementwise_ceil:
3599 case Builtin::BI__builtin_elementwise_cos:
3600 case Builtin::BI__builtin_elementwise_cosh:
3601 case Builtin::BI__builtin_elementwise_exp:
3602 case Builtin::BI__builtin_elementwise_exp2:
3603 case Builtin::BI__builtin_elementwise_exp10:
3604 case Builtin::BI__builtin_elementwise_floor:
3605 case Builtin::BI__builtin_elementwise_log:
3606 case Builtin::BI__builtin_elementwise_log2:
3607 case Builtin::BI__builtin_elementwise_log10:
3608 case Builtin::BI__builtin_elementwise_roundeven:
3609 case Builtin::BI__builtin_elementwise_round:
3610 case Builtin::BI__builtin_elementwise_rint:
3611 case Builtin::BI__builtin_elementwise_nearbyint:
3612 case Builtin::BI__builtin_elementwise_sin:
3613 case Builtin::BI__builtin_elementwise_sinh:
3614 case Builtin::BI__builtin_elementwise_sqrt:
3615 case Builtin::BI__builtin_elementwise_tan:
3616 case Builtin::BI__builtin_elementwise_tanh:
3617 case Builtin::BI__builtin_elementwise_trunc:
3618 case Builtin::BI__builtin_elementwise_canonicalize:
3623 case Builtin::BI__builtin_elementwise_fma:
3628 case Builtin::BI__builtin_elementwise_ldexp: {
3650 const auto *Vec0 = TyA->
getAs<VectorType>();
3651 const auto *Vec1 = TyExp->
getAs<VectorType>();
3652 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3654 if (Arg0Length != Arg1Length) {
3656 diag::err_typecheck_vector_lengths_not_equal)
3670 case Builtin::BI__builtin_elementwise_minnum:
3671 case Builtin::BI__builtin_elementwise_maxnum:
3672 case Builtin::BI__builtin_elementwise_minimum:
3673 case Builtin::BI__builtin_elementwise_maximum:
3674 case Builtin::BI__builtin_elementwise_minimumnum:
3675 case Builtin::BI__builtin_elementwise_maximumnum:
3676 case Builtin::BI__builtin_elementwise_atan2:
3677 case Builtin::BI__builtin_elementwise_fmod:
3678 case Builtin::BI__builtin_elementwise_pow:
3679 if (BuiltinElementwiseMath(TheCall,
3685 case Builtin::BI__builtin_elementwise_add_sat:
3686 case Builtin::BI__builtin_elementwise_sub_sat:
3687 case Builtin::BI__builtin_elementwise_clmul:
3688 if (BuiltinElementwiseMath(TheCall,
3692 case Builtin::BI__builtin_elementwise_fshl:
3693 case Builtin::BI__builtin_elementwise_fshr:
3698 case Builtin::BI__builtin_elementwise_min:
3699 case Builtin::BI__builtin_elementwise_max: {
3700 if (BuiltinElementwiseMath(TheCall))
3702 Expr *Arg0 = TheCall->
getArg(0);
3703 Expr *Arg1 = TheCall->
getArg(1);
3704 QualType Ty0 = Arg0->
getType();
3705 QualType Ty1 = Arg1->
getType();
3706 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3707 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3710 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3711 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3712 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3715 case Builtin::BI__builtin_elementwise_popcount:
3716 case Builtin::BI__builtin_elementwise_bitreverse:
3721 case Builtin::BI__builtin_elementwise_copysign: {
3730 QualType MagnitudeTy = Magnitude.
get()->
getType();
3743 diag::err_typecheck_call_different_arg_types)
3744 << MagnitudeTy << SignTy;
3752 case Builtin::BI__builtin_elementwise_clzg:
3753 case Builtin::BI__builtin_elementwise_ctzg:
3761 }
else if (BuiltinElementwiseMath(
3765 case Builtin::BI__builtin_reduce_max:
3766 case Builtin::BI__builtin_reduce_min: {
3767 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3770 const Expr *Arg = TheCall->
getArg(0);
3775 ElTy = TyA->getElementType();
3779 if (ElTy.isNull()) {
3789 case Builtin::BI__builtin_reduce_maximum:
3790 case Builtin::BI__builtin_reduce_minimum: {
3791 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3794 const Expr *Arg = TheCall->
getArg(0);
3799 ElTy = TyA->getElementType();
3803 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3816 case Builtin::BI__builtin_reduce_add:
3817 case Builtin::BI__builtin_reduce_mul:
3818 case Builtin::BI__builtin_reduce_xor:
3819 case Builtin::BI__builtin_reduce_or:
3820 case Builtin::BI__builtin_reduce_and: {
3821 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3824 const Expr *Arg = TheCall->
getArg(0);
3838 case Builtin::BI__builtin_reduce_assoc_fadd:
3839 case Builtin::BI__builtin_reduce_in_order_fadd: {
3841 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
3866 diag::err_builtin_invalid_arg_type)
3878 case Builtin::BI__builtin_matrix_transpose:
3879 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3881 case Builtin::BI__builtin_matrix_column_major_load:
3882 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3884 case Builtin::BI__builtin_matrix_column_major_store:
3885 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3887 case Builtin::BI__builtin_verbose_trap:
3892 case Builtin::BI__builtin_get_device_side_mangled_name: {
3893 auto Check = [](CallExpr *TheCall) {
3899 auto *D = DRE->getDecl();
3902 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3903 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3905 if (!Check(TheCall)) {
3907 diag::err_hip_invalid_args_builtin_mangled_name);
3912 case Builtin::BI__builtin_bswapg:
3916 case Builtin::BI__builtin_bitreverseg:
3920 case Builtin::BI__builtin_popcountg:
3924 case Builtin::BI__builtin_clzg:
3925 case Builtin::BI__builtin_ctzg:
3930 case Builtin::BI__builtin_stdc_rotate_left:
3931 case Builtin::BI__builtin_stdc_rotate_right:
3936 case Builtin::BI__builtin_stdc_bit_floor:
3937 case Builtin::BI__builtin_stdc_bit_ceil:
3941 case Builtin::BI__builtin_stdc_has_single_bit:
3945 case Builtin::BI__builtin_stdc_leading_zeros:
3946 case Builtin::BI__builtin_stdc_leading_ones:
3947 case Builtin::BI__builtin_stdc_trailing_zeros:
3948 case Builtin::BI__builtin_stdc_trailing_ones:
3949 case Builtin::BI__builtin_stdc_first_leading_zero:
3950 case Builtin::BI__builtin_stdc_first_leading_one:
3951 case Builtin::BI__builtin_stdc_first_trailing_zero:
3952 case Builtin::BI__builtin_stdc_first_trailing_one:
3953 case Builtin::BI__builtin_stdc_count_zeros:
3954 case Builtin::BI__builtin_stdc_count_ones:
3955 case Builtin::BI__builtin_stdc_bit_width:
3960 case Builtin::BI__builtin_allow_runtime_check: {
3961 Expr *Arg = TheCall->
getArg(0);
3971 case Builtin::BI__builtin_allow_sanitize_check: {
3975 Expr *Arg = TheCall->
getArg(0);
3977 const StringLiteral *SanitizerName =
3979 if (!SanitizerName) {
3985 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
3986 .Cases({
"address",
"thread",
"memory",
"hwaddress",
3987 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
3991 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
3997 case Builtin::BI__builtin_counted_by_ref:
3998 if (BuiltinCountedByRef(TheCall))
4008 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4009 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4010 assert(
Context.getAuxTargetInfo() &&
4011 "Aux Target Builtin, but not an aux target?");
4013 if (CheckTSBuiltinFunctionCall(
4015 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4018 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4024 return TheCallResult;
4039 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4043 diag::err_argument_not_contiguous_bit_field)
4050 bool IsVariadic =
false;
4053 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4054 IsVariadic = BD->isVariadic();
4055 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4056 IsVariadic = OMD->isVariadic();
4063 bool HasImplicitThisParam,
bool IsVariadic,
4067 else if (IsVariadic)
4077 if (HasImplicitThisParam) {
4109 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4110 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4111 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4112 Expr = ILE->getInit(0);
4122 const Expr *ArgExpr,
4126 S.
PDiag(diag::warn_null_arg)
4132 if (
auto nullability =
type->getNullability())
4143 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4149 llvm::SmallBitVector NonNullArgs;
4155 for (
const auto *Arg : Args)
4162 unsigned IdxAST = Idx.getASTIndex();
4163 if (IdxAST >= Args.size())
4165 if (NonNullArgs.empty())
4166 NonNullArgs.resize(Args.size());
4167 NonNullArgs.set(IdxAST);
4176 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4181 unsigned ParamIndex = 0;
4183 I != E; ++I, ++ParamIndex) {
4186 if (NonNullArgs.empty())
4187 NonNullArgs.resize(Args.size());
4189 NonNullArgs.set(ParamIndex);
4196 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4201 type = blockType->getPointeeType();
4215 if (NonNullArgs.empty())
4216 NonNullArgs.resize(Args.size());
4218 NonNullArgs.set(Index);
4227 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4228 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4229 if (NonNullArgs[ArgIndex])
4235 StringRef ParamName,
QualType ArgTy,
4258 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4259 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4263 if (ArgAlign < ParamAlign)
4264 Diag(Loc, diag::warn_param_mismatched_alignment)
4266 << ParamName << (FDecl !=
nullptr) << FDecl;
4270 const Expr *ThisArg,
4272 if (!FD || Args.empty())
4274 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4275 if (Idx == LifetimeCaptureByAttr::Global ||
4276 Idx == LifetimeCaptureByAttr::Unknown)
4278 if (IsMemberFunction && Idx == 0)
4280 return Args[Idx - IsMemberFunction];
4282 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4287 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4288 for (
int CapturingParamIdx :
Attr->params()) {
4289 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4293 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4296 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4304 I + IsMemberFunction);
4306 if (IsMemberFunction) {
4314 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4324 llvm::any_of(Args, [](
const Expr *E) {
4325 return E && E->isInstantiationDependent();
4330 llvm::SmallBitVector CheckedVarArgs;
4332 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4334 CheckedVarArgs.resize(Args.size());
4335 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4340 CheckedVarArgs.resize(Args.size());
4341 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4348 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4352 : isa_and_nonnull<FunctionDecl>(FDecl)
4354 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4358 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4360 if (
const Expr *Arg = Args[ArgIdx]) {
4361 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4368 if (FDecl || Proto) {
4373 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4374 CheckArgumentWithTypeTag(I, Args, Loc);
4380 if (!Proto && FDecl) {
4382 if (isa_and_nonnull<FunctionProtoType>(FT))
4388 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4390 bool IsScalableArg =
false;
4391 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4393 if (
const Expr *Arg = Args[ArgIdx]) {
4397 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4405 IsScalableArg =
true;
4407 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4416 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4417 llvm::StringMap<bool> CallerFeatureMap;
4418 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4419 if (!CallerFeatureMap.contains(
"sme"))
4420 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4421 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4422 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4431 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4433 (IsScalableArg || IsScalableRet)) {
4434 bool IsCalleeStreaming =
4436 bool IsCalleeStreamingCompatible =
4440 if (!IsCalleeStreamingCompatible &&
4444 unsigned VL = LO.VScaleMin * 128;
4445 unsigned SVL = LO.VScaleStreamingMin * 128;
4446 bool IsVLMismatch = VL && SVL && VL != SVL;
4448 auto EmitDiag = [&](
bool IsArg) {
4452 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4453 << IsArg << IsCalleeStreaming << SVL << VL;
4456 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4457 << IsArg << SVL << VL;
4459 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4476 bool CallerHasZAState =
false;
4477 bool CallerHasZT0State =
false;
4479 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4481 CallerHasZAState =
true;
4483 CallerHasZT0State =
true;
4487 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4489 CallerHasZT0State |=
4491 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4497 Diag(Loc, diag::err_sme_za_call_no_za_state);
4500 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4504 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4505 Diag(Loc, diag::note_sme_use_preserves_za);
4510 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4511 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4512 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4513 if (!Arg->isValueDependent()) {
4515 if (Arg->EvaluateAsInt(Align,
Context)) {
4516 const llvm::APSInt &I = Align.
Val.
getInt();
4517 if (!I.isPowerOf2())
4518 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4519 << Arg->getSourceRange();
4522 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4531 << diag::OffloadLang::SYCL;
4553 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4554 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4556 checkCall(FDecl, Proto,
nullptr, Args,
true,
4565 IsMemberOperatorCall;
4571 Expr *ImplicitThis =
nullptr;
4576 ImplicitThis = Args[0];
4579 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4590 ThisType =
Context.getPointerType(ThisType);
4596 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4614 CheckAbsoluteValueFunction(TheCall, FDecl);
4615 CheckMaxUnsignedZero(TheCall, FDecl);
4616 CheckInfNaNFunction(TheCall, FDecl);
4627 case Builtin::BIstrlcpy:
4628 case Builtin::BIstrlcat:
4629 CheckStrlcpycatArguments(TheCall, FnInfo);
4631 case Builtin::BIstrncat:
4632 CheckStrncatArguments(TheCall, FnInfo);
4634 case Builtin::BIfree:
4635 CheckFreeArguments(TheCall);
4638 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4647 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4648 Ty =
V->getType().getNonReferenceType();
4649 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4650 Ty = F->getType().getNonReferenceType();
4687 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4690 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4692 case AtomicExpr::AO__c11_atomic_init:
4693 case AtomicExpr::AO__opencl_atomic_init:
4694 llvm_unreachable(
"There is no ordering argument for an init");
4696 case AtomicExpr::AO__c11_atomic_load:
4697 case AtomicExpr::AO__opencl_atomic_load:
4698 case AtomicExpr::AO__hip_atomic_load:
4699 case AtomicExpr::AO__atomic_load_n:
4700 case AtomicExpr::AO__atomic_load:
4701 case AtomicExpr::AO__scoped_atomic_load_n:
4702 case AtomicExpr::AO__scoped_atomic_load:
4703 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4704 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4706 case AtomicExpr::AO__c11_atomic_store:
4707 case AtomicExpr::AO__opencl_atomic_store:
4708 case AtomicExpr::AO__hip_atomic_store:
4709 case AtomicExpr::AO__atomic_store:
4710 case AtomicExpr::AO__atomic_store_n:
4711 case AtomicExpr::AO__scoped_atomic_store:
4712 case AtomicExpr::AO__scoped_atomic_store_n:
4713 case AtomicExpr::AO__atomic_clear:
4714 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4715 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4716 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4746#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4747 case AtomicExpr::AO__hip_atomic_##hip: \
4748 OldName = "__hip_atomic_" #hip; \
4749 NewName = "__scoped_atomic_" #scoped; \
4762#undef HIP_ATOMIC_FIXABLE
4763 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4764 OldName =
"__hip_atomic_compare_exchange_weak";
4765 NewName =
"__scoped_atomic_compare_exchange";
4768 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4769 OldName =
"__hip_atomic_compare_exchange_strong";
4770 NewName =
"__scoped_atomic_compare_exchange";
4774 llvm_unreachable(
"unhandled HIP atomic op");
4777 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4778 << OldName << NewName;
4785 std::optional<llvm::APSInt> ScopeVal =
4790 StringRef ScopeName;
4791 switch (ScopeVal->getZExtValue()) {
4793 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4796 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4799 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4802 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4805 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
4808 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
4860 const unsigned NumForm = ClearByte + 1;
4861 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4862 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4870 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4871 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4872 "need to update code for modified forms");
4873 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4874 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4875 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4876 "need to update code for modified C11 atomics");
4877 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4878 Op <= AtomicExpr::AO__opencl_atomic_store;
4879 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4880 Op <= AtomicExpr::AO__hip_atomic_store;
4881 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4882 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4883 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4884 Op <= AtomicExpr::AO__c11_atomic_store) ||
4886 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4887 Op == AtomicExpr::AO__atomic_store_n ||
4888 Op == AtomicExpr::AO__atomic_exchange_n ||
4889 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4890 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4891 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4892 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4893 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4897 enum ArithOpExtraValueType {
4902 unsigned ArithAllows = AOEVT_None;
4905 case AtomicExpr::AO__c11_atomic_init:
4906 case AtomicExpr::AO__opencl_atomic_init:
4910 case AtomicExpr::AO__c11_atomic_load:
4911 case AtomicExpr::AO__opencl_atomic_load:
4912 case AtomicExpr::AO__hip_atomic_load:
4913 case AtomicExpr::AO__atomic_load_n:
4914 case AtomicExpr::AO__scoped_atomic_load_n:
4915 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4919 case AtomicExpr::AO__atomic_load:
4920 case AtomicExpr::AO__scoped_atomic_load:
4921 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4925 case AtomicExpr::AO__c11_atomic_store:
4926 case AtomicExpr::AO__opencl_atomic_store:
4927 case AtomicExpr::AO__hip_atomic_store:
4928 case AtomicExpr::AO__atomic_store:
4929 case AtomicExpr::AO__atomic_store_n:
4930 case AtomicExpr::AO__scoped_atomic_store:
4931 case AtomicExpr::AO__scoped_atomic_store_n:
4932 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4935 case AtomicExpr::AO__atomic_fetch_add:
4936 case AtomicExpr::AO__atomic_fetch_sub:
4937 case AtomicExpr::AO__atomic_add_fetch:
4938 case AtomicExpr::AO__atomic_sub_fetch:
4939 case AtomicExpr::AO__scoped_atomic_fetch_add:
4940 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4941 case AtomicExpr::AO__scoped_atomic_add_fetch:
4942 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4943 case AtomicExpr::AO__c11_atomic_fetch_add:
4944 case AtomicExpr::AO__c11_atomic_fetch_sub:
4945 case AtomicExpr::AO__opencl_atomic_fetch_add:
4946 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4947 case AtomicExpr::AO__hip_atomic_fetch_add:
4948 case AtomicExpr::AO__hip_atomic_fetch_sub:
4949 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4952 case AtomicExpr::AO__atomic_fetch_max:
4953 case AtomicExpr::AO__atomic_fetch_min:
4954 case AtomicExpr::AO__atomic_max_fetch:
4955 case AtomicExpr::AO__atomic_min_fetch:
4956 case AtomicExpr::AO__scoped_atomic_fetch_max:
4957 case AtomicExpr::AO__scoped_atomic_fetch_min:
4958 case AtomicExpr::AO__scoped_atomic_max_fetch:
4959 case AtomicExpr::AO__scoped_atomic_min_fetch:
4960 case AtomicExpr::AO__c11_atomic_fetch_max:
4961 case AtomicExpr::AO__c11_atomic_fetch_min:
4962 case AtomicExpr::AO__opencl_atomic_fetch_max:
4963 case AtomicExpr::AO__opencl_atomic_fetch_min:
4964 case AtomicExpr::AO__hip_atomic_fetch_max:
4965 case AtomicExpr::AO__hip_atomic_fetch_min:
4966 ArithAllows = AOEVT_FP;
4969 case AtomicExpr::AO__c11_atomic_fetch_and:
4970 case AtomicExpr::AO__c11_atomic_fetch_or:
4971 case AtomicExpr::AO__c11_atomic_fetch_xor:
4972 case AtomicExpr::AO__hip_atomic_fetch_and:
4973 case AtomicExpr::AO__hip_atomic_fetch_or:
4974 case AtomicExpr::AO__hip_atomic_fetch_xor:
4975 case AtomicExpr::AO__c11_atomic_fetch_nand:
4976 case AtomicExpr::AO__opencl_atomic_fetch_and:
4977 case AtomicExpr::AO__opencl_atomic_fetch_or:
4978 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4979 case AtomicExpr::AO__atomic_fetch_and:
4980 case AtomicExpr::AO__atomic_fetch_or:
4981 case AtomicExpr::AO__atomic_fetch_xor:
4982 case AtomicExpr::AO__atomic_fetch_nand:
4983 case AtomicExpr::AO__atomic_and_fetch:
4984 case AtomicExpr::AO__atomic_or_fetch:
4985 case AtomicExpr::AO__atomic_xor_fetch:
4986 case AtomicExpr::AO__atomic_nand_fetch:
4987 case AtomicExpr::AO__atomic_fetch_uinc:
4988 case AtomicExpr::AO__atomic_fetch_udec:
4989 case AtomicExpr::AO__scoped_atomic_fetch_and:
4990 case AtomicExpr::AO__scoped_atomic_fetch_or:
4991 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4992 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4993 case AtomicExpr::AO__scoped_atomic_and_fetch:
4994 case AtomicExpr::AO__scoped_atomic_or_fetch:
4995 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4996 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4997 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
4998 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5002 case AtomicExpr::AO__c11_atomic_exchange:
5003 case AtomicExpr::AO__hip_atomic_exchange:
5004 case AtomicExpr::AO__opencl_atomic_exchange:
5005 case AtomicExpr::AO__atomic_exchange_n:
5006 case AtomicExpr::AO__scoped_atomic_exchange_n:
5007 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5011 case AtomicExpr::AO__atomic_exchange:
5012 case AtomicExpr::AO__scoped_atomic_exchange:
5013 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5017 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5018 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5019 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5020 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5021 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5022 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5026 case AtomicExpr::AO__atomic_compare_exchange:
5027 case AtomicExpr::AO__atomic_compare_exchange_n:
5028 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5029 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5030 ArithAllows = AOEVT_Pointer;
5034 case AtomicExpr::AO__atomic_test_and_set:
5035 Form = TestAndSetByte;
5038 case AtomicExpr::AO__atomic_clear:
5043 unsigned AdjustedNumArgs = NumArgs[Form];
5044 if ((IsOpenCL || IsHIP || IsScoped) &&
5045 Op != AtomicExpr::AO__opencl_atomic_init)
5048 if (Args.size() < AdjustedNumArgs) {
5049 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5050 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5053 }
else if (Args.size() > AdjustedNumArgs) {
5054 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5055 diag::err_typecheck_call_too_many_args)
5056 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5062 Expr *Ptr = Args[0];
5067 Ptr = ConvertedPtr.
get();
5070 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5080 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5086 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5092 }
else if (Form != Load && Form != LoadCopy) {
5094 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5100 if (Form != TestAndSetByte && Form != ClearByte) {
5103 diag::err_incomplete_type))
5106 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5107 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5117 pointerType->getPointeeType().getCVRQualifiers());
5127 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5137 auto IsAllowedValueType = [&](
QualType ValType,
5138 unsigned AllowedType) ->
bool {
5139 bool IsX87LongDouble =
5141 &
Context.getTargetInfo().getLongDoubleFormat() ==
5142 &llvm::APFloat::x87DoubleExtended();
5146 return AllowedType & AOEVT_Pointer;
5150 if (IsX87LongDouble)
5154 if (!IsAllowedValueType(ValType, ArithAllows)) {
5155 auto DID = ArithAllows & AOEVT_FP
5156 ? (ArithAllows & AOEVT_Pointer
5157 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5158 : diag::err_atomic_op_needs_atomic_int_or_fp)
5159 : (ArithAllows & AOEVT_Pointer
5160 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5161 : diag::err_atomic_op_needs_atomic_int);
5168 diag::err_incomplete_type)) {
5179 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5195 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5207 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5210 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5216 bool IsPassedByAddress =
false;
5217 if (!IsC11 && !IsHIP && !IsN) {
5219 IsPassedByAddress =
true;
5224 APIOrderedArgs.push_back(Args[0]);
5228 APIOrderedArgs.push_back(Args[1]);
5234 APIOrderedArgs.push_back(Args[2]);
5235 APIOrderedArgs.push_back(Args[1]);
5238 APIOrderedArgs.push_back(Args[2]);
5239 APIOrderedArgs.push_back(Args[3]);
5240 APIOrderedArgs.push_back(Args[1]);
5243 APIOrderedArgs.push_back(Args[2]);
5244 APIOrderedArgs.push_back(Args[4]);
5245 APIOrderedArgs.push_back(Args[1]);
5246 APIOrderedArgs.push_back(Args[3]);
5249 APIOrderedArgs.push_back(Args[2]);
5250 APIOrderedArgs.push_back(Args[4]);
5251 APIOrderedArgs.push_back(Args[5]);
5252 APIOrderedArgs.push_back(Args[1]);
5253 APIOrderedArgs.push_back(Args[3]);
5255 case TestAndSetByte:
5257 APIOrderedArgs.push_back(Args[1]);
5261 APIOrderedArgs.append(Args.begin(), Args.end());
5268 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5270 if (i < NumVals[Form] + 1) {
5283 assert(Form != Load);
5285 Ty =
Context.getPointerDiffType();
5288 else if (Form ==
Copy || Form == Xchg) {
5289 if (IsPassedByAddress) {
5296 Expr *ValArg = APIOrderedArgs[i];
5303 AS = PtrTy->getPointeeType().getAddressSpace();
5312 if (IsPassedByAddress)
5332 APIOrderedArgs[i] = Arg.
get();
5337 SubExprs.push_back(Ptr);
5341 SubExprs.push_back(APIOrderedArgs[1]);
5344 case TestAndSetByte:
5346 SubExprs.push_back(APIOrderedArgs[1]);
5352 SubExprs.push_back(APIOrderedArgs[2]);
5353 SubExprs.push_back(APIOrderedArgs[1]);
5357 SubExprs.push_back(APIOrderedArgs[3]);
5358 SubExprs.push_back(APIOrderedArgs[1]);
5359 SubExprs.push_back(APIOrderedArgs[2]);
5362 SubExprs.push_back(APIOrderedArgs[3]);
5363 SubExprs.push_back(APIOrderedArgs[1]);
5364 SubExprs.push_back(APIOrderedArgs[4]);
5365 SubExprs.push_back(APIOrderedArgs[2]);
5368 SubExprs.push_back(APIOrderedArgs[4]);
5369 SubExprs.push_back(APIOrderedArgs[1]);
5370 SubExprs.push_back(APIOrderedArgs[5]);
5371 SubExprs.push_back(APIOrderedArgs[2]);
5372 SubExprs.push_back(APIOrderedArgs[3]);
5377 if (SubExprs.size() >= 2 && Form !=
Init) {
5378 std::optional<llvm::APSInt>
Success =
5379 SubExprs[1]->getIntegerConstantExpr(
Context);
5381 Diag(SubExprs[1]->getBeginLoc(),
5382 diag::warn_atomic_op_has_invalid_memory_order)
5383 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5384 << SubExprs[1]->getSourceRange();
5386 if (SubExprs.size() >= 5) {
5387 if (std::optional<llvm::APSInt>
Failure =
5388 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5389 if (!llvm::is_contained(
5390 {llvm::AtomicOrderingCABI::relaxed,
5391 llvm::AtomicOrderingCABI::consume,
5392 llvm::AtomicOrderingCABI::acquire,
5393 llvm::AtomicOrderingCABI::seq_cst},
5394 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5395 Diag(SubExprs[3]->getBeginLoc(),
5396 diag::warn_atomic_op_has_invalid_memory_order)
5397 << 2 << SubExprs[3]->getSourceRange();
5404 auto *
Scope = Args[Args.size() - 1];
5405 if (std::optional<llvm::APSInt>
Result =
5407 if (!ScopeModel->isValid(
Result->getZExtValue()))
5408 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5409 <<
Scope->getSourceRange();
5411 SubExprs.push_back(
Scope);
5420 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5421 Op == AtomicExpr::AO__c11_atomic_store ||
5422 Op == AtomicExpr::AO__opencl_atomic_load ||
5423 Op == AtomicExpr::AO__hip_atomic_load ||
5424 Op == AtomicExpr::AO__opencl_atomic_store ||
5425 Op == AtomicExpr::AO__hip_atomic_store) &&
5426 Context.AtomicUsesUnsupportedLibcall(AE))
5428 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5429 Op == AtomicExpr::AO__opencl_atomic_load ||
5430 Op == AtomicExpr::AO__hip_atomic_load)
5435 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5451 assert(Fn &&
"builtin call without direct callee!");
5467 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5474 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5476 <<
Callee->getSourceRange();
5485 Expr *FirstArg = TheCall->
getArg(0);
5489 FirstArg = FirstArgResult.
get();
5490 TheCall->
setArg(0, FirstArg);
5502 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5509 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5539 QualType ResultType = ValType;
5544#define BUILTIN_ROW(x) \
5545 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5546 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5548 static const unsigned BuiltinIndices[][5] = {
5573 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5574 case 1: SizeIndex = 0;
break;
5575 case 2: SizeIndex = 1;
break;
5576 case 4: SizeIndex = 2;
break;
5577 case 8: SizeIndex = 3;
break;
5578 case 16: SizeIndex = 4;
break;
5590 unsigned BuiltinIndex, NumFixed = 1;
5591 bool WarnAboutSemanticsChange =
false;
5592 switch (BuiltinID) {
5593 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5594 case Builtin::BI__sync_fetch_and_add:
5595 case Builtin::BI__sync_fetch_and_add_1:
5596 case Builtin::BI__sync_fetch_and_add_2:
5597 case Builtin::BI__sync_fetch_and_add_4:
5598 case Builtin::BI__sync_fetch_and_add_8:
5599 case Builtin::BI__sync_fetch_and_add_16:
5603 case Builtin::BI__sync_fetch_and_sub:
5604 case Builtin::BI__sync_fetch_and_sub_1:
5605 case Builtin::BI__sync_fetch_and_sub_2:
5606 case Builtin::BI__sync_fetch_and_sub_4:
5607 case Builtin::BI__sync_fetch_and_sub_8:
5608 case Builtin::BI__sync_fetch_and_sub_16:
5612 case Builtin::BI__sync_fetch_and_or:
5613 case Builtin::BI__sync_fetch_and_or_1:
5614 case Builtin::BI__sync_fetch_and_or_2:
5615 case Builtin::BI__sync_fetch_and_or_4:
5616 case Builtin::BI__sync_fetch_and_or_8:
5617 case Builtin::BI__sync_fetch_and_or_16:
5621 case Builtin::BI__sync_fetch_and_and:
5622 case Builtin::BI__sync_fetch_and_and_1:
5623 case Builtin::BI__sync_fetch_and_and_2:
5624 case Builtin::BI__sync_fetch_and_and_4:
5625 case Builtin::BI__sync_fetch_and_and_8:
5626 case Builtin::BI__sync_fetch_and_and_16:
5630 case Builtin::BI__sync_fetch_and_xor:
5631 case Builtin::BI__sync_fetch_and_xor_1:
5632 case Builtin::BI__sync_fetch_and_xor_2:
5633 case Builtin::BI__sync_fetch_and_xor_4:
5634 case Builtin::BI__sync_fetch_and_xor_8:
5635 case Builtin::BI__sync_fetch_and_xor_16:
5639 case Builtin::BI__sync_fetch_and_nand:
5640 case Builtin::BI__sync_fetch_and_nand_1:
5641 case Builtin::BI__sync_fetch_and_nand_2:
5642 case Builtin::BI__sync_fetch_and_nand_4:
5643 case Builtin::BI__sync_fetch_and_nand_8:
5644 case Builtin::BI__sync_fetch_and_nand_16:
5646 WarnAboutSemanticsChange =
true;
5649 case Builtin::BI__sync_add_and_fetch:
5650 case Builtin::BI__sync_add_and_fetch_1:
5651 case Builtin::BI__sync_add_and_fetch_2:
5652 case Builtin::BI__sync_add_and_fetch_4:
5653 case Builtin::BI__sync_add_and_fetch_8:
5654 case Builtin::BI__sync_add_and_fetch_16:
5658 case Builtin::BI__sync_sub_and_fetch:
5659 case Builtin::BI__sync_sub_and_fetch_1:
5660 case Builtin::BI__sync_sub_and_fetch_2:
5661 case Builtin::BI__sync_sub_and_fetch_4:
5662 case Builtin::BI__sync_sub_and_fetch_8:
5663 case Builtin::BI__sync_sub_and_fetch_16:
5667 case Builtin::BI__sync_and_and_fetch:
5668 case Builtin::BI__sync_and_and_fetch_1:
5669 case Builtin::BI__sync_and_and_fetch_2:
5670 case Builtin::BI__sync_and_and_fetch_4:
5671 case Builtin::BI__sync_and_and_fetch_8:
5672 case Builtin::BI__sync_and_and_fetch_16:
5676 case Builtin::BI__sync_or_and_fetch:
5677 case Builtin::BI__sync_or_and_fetch_1:
5678 case Builtin::BI__sync_or_and_fetch_2:
5679 case Builtin::BI__sync_or_and_fetch_4:
5680 case Builtin::BI__sync_or_and_fetch_8:
5681 case Builtin::BI__sync_or_and_fetch_16:
5685 case Builtin::BI__sync_xor_and_fetch:
5686 case Builtin::BI__sync_xor_and_fetch_1:
5687 case Builtin::BI__sync_xor_and_fetch_2:
5688 case Builtin::BI__sync_xor_and_fetch_4:
5689 case Builtin::BI__sync_xor_and_fetch_8:
5690 case Builtin::BI__sync_xor_and_fetch_16:
5694 case Builtin::BI__sync_nand_and_fetch:
5695 case Builtin::BI__sync_nand_and_fetch_1:
5696 case Builtin::BI__sync_nand_and_fetch_2:
5697 case Builtin::BI__sync_nand_and_fetch_4:
5698 case Builtin::BI__sync_nand_and_fetch_8:
5699 case Builtin::BI__sync_nand_and_fetch_16:
5701 WarnAboutSemanticsChange =
true;
5704 case Builtin::BI__sync_val_compare_and_swap:
5705 case Builtin::BI__sync_val_compare_and_swap_1:
5706 case Builtin::BI__sync_val_compare_and_swap_2:
5707 case Builtin::BI__sync_val_compare_and_swap_4:
5708 case Builtin::BI__sync_val_compare_and_swap_8:
5709 case Builtin::BI__sync_val_compare_and_swap_16:
5714 case Builtin::BI__sync_bool_compare_and_swap:
5715 case Builtin::BI__sync_bool_compare_and_swap_1:
5716 case Builtin::BI__sync_bool_compare_and_swap_2:
5717 case Builtin::BI__sync_bool_compare_and_swap_4:
5718 case Builtin::BI__sync_bool_compare_and_swap_8:
5719 case Builtin::BI__sync_bool_compare_and_swap_16:
5725 case Builtin::BI__sync_lock_test_and_set:
5726 case Builtin::BI__sync_lock_test_and_set_1:
5727 case Builtin::BI__sync_lock_test_and_set_2:
5728 case Builtin::BI__sync_lock_test_and_set_4:
5729 case Builtin::BI__sync_lock_test_and_set_8:
5730 case Builtin::BI__sync_lock_test_and_set_16:
5734 case Builtin::BI__sync_lock_release:
5735 case Builtin::BI__sync_lock_release_1:
5736 case Builtin::BI__sync_lock_release_2:
5737 case Builtin::BI__sync_lock_release_4:
5738 case Builtin::BI__sync_lock_release_8:
5739 case Builtin::BI__sync_lock_release_16:
5745 case Builtin::BI__sync_swap:
5746 case Builtin::BI__sync_swap_1:
5747 case Builtin::BI__sync_swap_2:
5748 case Builtin::BI__sync_swap_4:
5749 case Builtin::BI__sync_swap_8:
5750 case Builtin::BI__sync_swap_16:
5758 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5759 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5760 <<
Callee->getSourceRange();
5764 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5765 <<
Callee->getSourceRange();
5767 if (WarnAboutSemanticsChange) {
5768 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5769 <<
Callee->getSourceRange();
5774 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5775 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5776 FunctionDecl *NewBuiltinDecl;
5777 if (NewBuiltinID == BuiltinID)
5778 NewBuiltinDecl = FDecl;
5781 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5784 assert(Res.getFoundDecl());
5785 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5786 if (!NewBuiltinDecl)
5793 for (
unsigned i = 0; i != NumFixed; ++i) {
5822 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5824 CK_BuiltinFnToFnPtr);
5835 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5836 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5837 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5841 return TheCallResult;
5845 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5850 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5851 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5852 "Unexpected nontemporal load/store builtin!");
5853 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5854 unsigned numArgs = isStore ? 2 : 1;
5864 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5870 PointerArg = PointerArgResult.
get();
5871 TheCall->
setArg(numArgs - 1, PointerArg);
5875 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5888 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5895 return TheCallResult;
5907 return TheCallResult;
5914 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5916 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5917 Literal = ObjcLiteral->getString();
5921 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5928 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5929 InitializedEntity Entity =
5939 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5940 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5941 TT.getArch() == llvm::Triple::aarch64_32);
5942 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5943 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5944 if (IsX64 || IsAArch64) {
5951 return S.
Diag(Fn->getBeginLoc(),
5952 diag::err_ms_va_start_used_in_sysv_function);
5959 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5960 return S.
Diag(Fn->getBeginLoc(),
5961 diag::err_va_start_used_in_wrong_abi_function)
5962 << !IsWindowsOrUEFI;
5968 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5976 bool IsVariadic =
false;
5979 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5980 IsVariadic =
Block->isVariadic();
5981 Params =
Block->parameters();
5982 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5985 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5986 IsVariadic = MD->isVariadic();
5988 Params = MD->parameters();
5991 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5995 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6000 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6005 *LastParam = Params.empty() ?
nullptr : Params.back();
6010bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6015 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6039 ParmVarDecl *LastParam;
6050 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6052 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6057 if (std::optional<llvm::APSInt> Val =
6059 Val &&
LangOpts.C23 && *Val == 0 &&
6060 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6061 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6068 SourceLocation ParamLoc;
6069 bool IsCRegister =
false;
6070 bool SecondArgIsLastNonVariadicArgument =
false;
6071 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6072 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6073 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6076 ParamLoc = PV->getLocation();
6082 if (!SecondArgIsLastNonVariadicArgument)
6084 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6085 else if (IsCRegister ||
Type->isReferenceType() ||
6086 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6089 if (!Context.isPromotableIntegerType(Type))
6091 const auto *ED = Type->getAsEnumDecl();
6094 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6096 unsigned Reason = 0;
6097 if (
Type->isReferenceType()) Reason = 1;
6098 else if (IsCRegister) Reason = 2;
6099 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6100 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6107 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6127 if (
Call->getNumArgs() < 3)
6129 diag::err_typecheck_call_too_few_args_at_least)
6130 << 0 << 3 <<
Call->getNumArgs()
6146 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6149 const QualType &ConstCharPtrTy =
6151 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6153 << Arg1->
getType() << ConstCharPtrTy << 1
6156 << 2 << Arg1->
getType() << ConstCharPtrTy;
6158 const QualType SizeTy =
Context.getSizeType();
6163 << Arg2->
getType() << SizeTy << 1
6166 << 3 << Arg2->
getType() << SizeTy;
6171bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6175 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6203 diag::err_typecheck_call_invalid_ordered_compare)
6211bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6212 unsigned BuiltinID) {
6217 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6218 BuiltinID == Builtin::BI__builtin_isinf ||
6219 BuiltinID == Builtin::BI__builtin_isinf_sign))
6223 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6224 BuiltinID == Builtin::BI__builtin_isunordered))
6228 bool IsFPClass = NumArgs == 2;
6231 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6235 for (
unsigned i = 0; i < FPArgNo; ++i) {
6236 Expr *Arg = TheCall->
getArg(i);
6249 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6257 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
6262 OrigArg = Res.
get();
6268 OrigArg = Res.
get();
6270 TheCall->
setArg(FPArgNo, OrigArg);
6272 QualType VectorResultTy;
6273 QualType ElementTy = OrigArg->
getType();
6278 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6284 diag::err_typecheck_call_invalid_unary_fp)
6296 if (!VectorResultTy.
isNull())
6297 ResultTy = VectorResultTy;
6306bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6311 for (
unsigned I = 0; I != 2; ++I) {
6312 Expr *Arg = TheCall->
getArg(I);
6322 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6337 Expr *Real = TheCall->
getArg(0);
6338 Expr *Imag = TheCall->
getArg(1);
6341 diag::err_typecheck_call_different_arg_types)
6356 diag::err_typecheck_call_too_few_args_at_least)
6357 << 0 << 2 << NumArgs
6364 unsigned NumElements = 0;
6379 unsigned NumResElements = NumArgs - 2;
6388 diag::err_vec_builtin_incompatible_vector)
6393 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6395 diag::err_vec_builtin_incompatible_vector)
6400 }
else if (NumElements != NumResElements) {
6403 ?
Context.getExtVectorType(EltType, NumResElements)
6404 :
Context.getVectorType(EltType, NumResElements,
6409 for (
unsigned I = 2; I != NumArgs; ++I) {
6417 diag::err_shufflevector_nonconstant_argument)
6423 else if (
Result->getActiveBits() > 64 ||
6424 Result->getZExtValue() >= NumElements * 2)
6426 diag::err_shufflevector_argument_too_large)
6451 diag::err_convertvector_non_vector)
6454 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6456 <<
"__builtin_convertvector");
6461 if (SrcElts != DstElts)
6463 diag::err_convertvector_incompatible_vector)
6471bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6476 diag::err_typecheck_call_too_many_args_at_most)
6477 << 0 << 3 << NumArgs << 0
6482 for (
unsigned i = 1; i != NumArgs; ++i)
6489bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6490 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6491 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6501 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6511bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6512 Expr *Arg = TheCall->
getArg(0);
6523bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6525 Expr *Arg = TheCall->
getArg(1);
6529 if (
const auto *UE =
6531 if (UE->getKind() == UETT_AlignOf ||
6532 UE->getKind() == UETT_PreferredAlignOf)
6538 if (!
Result.isPowerOf2())
6539 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6546 if (
Result > std::numeric_limits<int32_t>::max())
6554bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6559 Expr *FirstArg = TheCall->
getArg(0);
6565 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6569 TheCall->
setArg(0, FirstArgResult.
get());
6573 Expr *SecondArg = TheCall->
getArg(1);
6581 if (!
Result.isPowerOf2())
6582 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6594 Expr *ThirdArg = TheCall->
getArg(2);
6597 TheCall->
setArg(2, ThirdArg);
6603bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6604 unsigned BuiltinID =
6606 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6609 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6610 if (NumArgs < NumRequiredArgs) {
6611 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6612 << 0 << NumRequiredArgs << NumArgs
6615 if (NumArgs >= NumRequiredArgs + 0x100) {
6617 diag::err_typecheck_call_too_many_args_at_most)
6618 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6629 if (Arg.isInvalid())
6631 TheCall->
setArg(i, Arg.get());
6636 unsigned FormatIdx = i;
6646 unsigned FirstDataArg = i;
6647 while (i < NumArgs) {
6665 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6667 bool Success = CheckFormatArguments(
6670 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6694 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6703 int High,
bool RangeIsError) {
6717 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6725 PDiag(diag::warn_argument_invalid_range)
6768 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6773 if (
Value.isNegative())
6784 if ((
Value & 0xFF) != 0)
6809 Result.setIsUnsigned(
true);
6814 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6834 Result.setIsUnsigned(
true);
6842 diag::err_argument_not_shifted_byte_or_xxff)
6846bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6847 if (!Context.getTargetInfo().hasSjLjLowering())
6848 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6859 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6865bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6866 if (!Context.getTargetInfo().hasSjLjLowering())
6867 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6872bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6887 diag::err_builtin_counted_by_ref_invalid_arg)
6892 diag::err_builtin_counted_by_ref_has_side_effects)
6895 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6897 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6902 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6909 QualType MemberTy = ME->getMemberDecl()->getType();
6912 diag::err_builtin_counted_by_ref_invalid_arg)
6916 diag::err_builtin_counted_by_ref_invalid_arg)
6926bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6928 const CallExpr *CE =
6937 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6942 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6947 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6951 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6955 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6965class UncoveredArgHandler {
6966 enum {
Unknown = -1, AllCovered = -2 };
6968 signed FirstUncoveredArg =
Unknown;
6969 SmallVector<const Expr *, 4> DiagnosticExprs;
6972 UncoveredArgHandler() =
default;
6974 bool hasUncoveredArg()
const {
6975 return (FirstUncoveredArg >= 0);
6978 unsigned getUncoveredArg()
const {
6979 assert(hasUncoveredArg() &&
"no uncovered argument");
6980 return FirstUncoveredArg;
6983 void setAllCovered() {
6986 DiagnosticExprs.clear();
6987 FirstUncoveredArg = AllCovered;
6990 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6991 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6994 if (FirstUncoveredArg == AllCovered)
6999 if (NewFirstUncoveredArg == FirstUncoveredArg)
7000 DiagnosticExprs.push_back(StrExpr);
7001 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7002 DiagnosticExprs.clear();
7003 DiagnosticExprs.push_back(StrExpr);
7004 FirstUncoveredArg = NewFirstUncoveredArg;
7008 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7011enum StringLiteralCheckType {
7013 SLCT_UncheckedLiteral,
7021 bool AddendIsRight) {
7022 unsigned BitWidth = Offset.getBitWidth();
7023 unsigned AddendBitWidth = Addend.getBitWidth();
7025 if (Addend.isUnsigned()) {
7026 Addend = Addend.zext(++AddendBitWidth);
7027 Addend.setIsSigned(
true);
7030 if (AddendBitWidth > BitWidth) {
7031 Offset = Offset.sext(AddendBitWidth);
7032 BitWidth = AddendBitWidth;
7033 }
else if (BitWidth > AddendBitWidth) {
7034 Addend = Addend.sext(BitWidth);
7038 llvm::APSInt ResOffset = Offset;
7039 if (BinOpKind == BO_Add)
7040 ResOffset = Offset.sadd_ov(Addend, Ov);
7042 assert(AddendIsRight && BinOpKind == BO_Sub &&
7043 "operator must be add or sub with addend on the right");
7044 ResOffset = Offset.ssub_ov(Addend, Ov);
7050 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7051 "index (intermediate) result too big");
7052 Offset = Offset.sext(2 * BitWidth);
7053 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7057 Offset = std::move(ResOffset);
7065class FormatStringLiteral {
7066 const StringLiteral *FExpr;
7070 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7071 : FExpr(fexpr), Offset(Offset) {}
7073 const StringLiteral *getFormatString()
const {
return FExpr; }
7075 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7077 unsigned getByteLength()
const {
7078 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7081 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7088 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7089 bool isWide()
const {
return FExpr->
isWide(); }
7090 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7091 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7092 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7093 bool isPascal()
const {
return FExpr->
isPascal(); }
7095 SourceLocation getLocationOfByte(
7096 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
7097 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7098 unsigned *StartTokenByteOffset =
nullptr)
const {
7100 StartToken, StartTokenByteOffset);
7103 SourceLocation getBeginLoc() const LLVM_READONLY {
7107 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7113 Sema &S,
const FormatStringLiteral *FExpr,
7118 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7119 bool IgnoreStringsWithoutSpecifiers);
7128static StringLiteralCheckType
7134 llvm::SmallBitVector &CheckedVarArgs,
7135 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7136 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7137 bool IgnoreStringsWithoutSpecifiers =
false) {
7139 return SLCT_NotALiteral;
7141 assert(Offset.isSigned() &&
"invalid offset");
7144 return SLCT_NotALiteral;
7153 return SLCT_UncheckedLiteral;
7156 case Stmt::InitListExprClass:
7160 format_idx, firstDataArg,
Type, CallType,
7161 false, CheckedVarArgs,
7162 UncoveredArg, Offset, CallerFormatParamIdx,
7163 IgnoreStringsWithoutSpecifiers);
7165 return SLCT_NotALiteral;
7166 case Stmt::BinaryConditionalOperatorClass:
7167 case Stmt::ConditionalOperatorClass: {
7176 bool CheckLeft =
true, CheckRight =
true;
7179 if (
C->getCond()->EvaluateAsBooleanCondition(
7191 StringLiteralCheckType Left;
7193 Left = SLCT_UncheckedLiteral;
7196 Args, APK, format_idx, firstDataArg,
Type,
7197 CallType, InFunctionCall, CheckedVarArgs,
7198 UncoveredArg, Offset, CallerFormatParamIdx,
7199 IgnoreStringsWithoutSpecifiers);
7200 if (Left == SLCT_NotALiteral || !CheckRight) {
7206 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7207 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7208 UncoveredArg, Offset, CallerFormatParamIdx,
7209 IgnoreStringsWithoutSpecifiers);
7211 return (CheckLeft && Left < Right) ? Left : Right;
7214 case Stmt::ImplicitCastExprClass:
7218 case Stmt::OpaqueValueExprClass:
7223 return SLCT_NotALiteral;
7225 case Stmt::PredefinedExprClass:
7229 return SLCT_UncheckedLiteral;
7231 case Stmt::DeclRefExprClass: {
7237 bool isConstant =
false;
7241 isConstant = AT->getElementType().isConstant(S.
Context);
7243 isConstant = T.isConstant(S.
Context) &&
7244 PT->getPointeeType().isConstant(S.
Context);
7245 }
else if (T->isObjCObjectPointerType()) {
7248 isConstant = T.isConstant(S.
Context);
7252 if (
const Expr *
Init = VD->getAnyInitializer()) {
7255 if (InitList->isStringLiteralInit())
7256 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7259 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7260 firstDataArg,
Type, CallType,
false,
7261 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7312 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7313 if (CallerFormatParamIdx)
7314 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7315 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7316 for (
const auto *PVFormatMatches :
7317 D->specific_attrs<FormatMatchesAttr>()) {
7322 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7326 S.
Diag(Args[format_idx]->getBeginLoc(),
7327 diag::warn_format_string_type_incompatible)
7328 << PVFormatMatches->getType()->getName()
7330 if (!InFunctionCall) {
7331 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7332 diag::note_format_string_defined);
7334 return SLCT_UncheckedLiteral;
7337 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7338 Args, APK, format_idx, firstDataArg,
Type, CallType,
7339 false, CheckedVarArgs, UncoveredArg,
7340 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7344 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7347 PVFormat->getFirstArg(), &CallerFSI))
7349 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7353 S.
Diag(Args[format_idx]->getBeginLoc(),
7354 diag::warn_format_string_type_incompatible)
7355 << PVFormat->getType()->getName()
7357 if (!InFunctionCall) {
7360 return SLCT_UncheckedLiteral;
7373 return SLCT_UncheckedLiteral;
7381 return SLCT_NotALiteral;
7384 case Stmt::CallExprClass:
7385 case Stmt::CXXMemberCallExprClass: {
7389 StringLiteralCheckType CommonResult;
7390 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7391 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7393 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7394 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7395 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7402 return CommonResult;
7404 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7406 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7407 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7410 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7411 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7412 UncoveredArg, Offset, CallerFormatParamIdx,
7413 IgnoreStringsWithoutSpecifiers);
7419 format_idx, firstDataArg,
Type, CallType,
7420 false, CheckedVarArgs,
7421 UncoveredArg, Offset, CallerFormatParamIdx,
7422 IgnoreStringsWithoutSpecifiers);
7423 return SLCT_NotALiteral;
7425 case Stmt::ObjCMessageExprClass: {
7427 if (
const auto *MD = ME->getMethodDecl()) {
7428 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7437 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7439 MD->getSelector().isKeywordSelector(
7440 {
"localizedStringForKey",
"value",
"table"})) {
7441 IgnoreStringsWithoutSpecifiers =
true;
7444 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7446 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7447 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7448 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7452 return SLCT_NotALiteral;
7454 case Stmt::ObjCStringLiteralClass:
7455 case Stmt::StringLiteralClass: {
7464 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7467 return SLCT_NotALiteral;
7469 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7471 format_idx, firstDataArg,
Type, InFunctionCall,
7472 CallType, CheckedVarArgs, UncoveredArg,
7473 IgnoreStringsWithoutSpecifiers);
7474 return SLCT_CheckedLiteral;
7477 return SLCT_NotALiteral;
7479 case Stmt::BinaryOperatorClass: {
7493 if (LIsInt != RIsInt) {
7497 if (BinOpKind == BO_Add) {
7510 return SLCT_NotALiteral;
7512 case Stmt::UnaryOperatorClass: {
7514 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7515 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7517 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7527 return SLCT_NotALiteral;
7531 return SLCT_NotALiteral;
7542 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7543 if (isa_and_nonnull<StringLiteral>(LVE))
7564 return "freebsd_kprintf";
7573 return llvm::StringSwitch<FormatStringType>(Flavor)
7575 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7580 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7596bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7600 llvm::SmallBitVector &CheckedVarArgs) {
7601 FormatStringInfo FSI;
7605 return CheckFormatArguments(
7606 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7611bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7615 llvm::SmallBitVector &CheckedVarArgs) {
7616 FormatStringInfo FSI;
7620 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7621 Format->getFormatString(), FSI.FormatIdx,
7623 CallType, Loc, Range, CheckedVarArgs);
7631 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7644 unsigned CallerArgumentIndexOffset =
7647 unsigned FirstArgumentIndex = -1;
7657 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7658 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7662 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7663 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7665 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7668 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7669 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7672 FirstArgumentIndex =
7673 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7679 ? (NumCallerParams + CallerArgumentIndexOffset)
7684 if (!ReferenceFormatString)
7690 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7692 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7694 std::string
Attr, Fixit;
7695 llvm::raw_string_ostream AttrOS(
Attr);
7697 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7698 << FirstArgumentIndex <<
")";
7700 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7702 AttrOS.write_escaped(ReferenceFormatString->
getString());
7706 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7717 llvm::raw_string_ostream IS(Fixit);
7725 if (LO.C23 || LO.CPlusPlus11)
7726 IS <<
"[[gnu::" <<
Attr <<
"]]";
7727 else if (LO.ObjC || LO.GNUMode)
7728 IS <<
"__attribute__((" <<
Attr <<
"))";
7742 Caller->
addAttr(FormatAttr::CreateImplicit(
7744 FormatStringIndex, FirstArgumentIndex));
7746 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7748 FormatStringIndex, ReferenceFormatString));
7752 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7764 unsigned format_idx,
unsigned firstDataArg,
7768 llvm::SmallBitVector &CheckedVarArgs) {
7770 if (format_idx >= Args.size()) {
7771 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7775 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7789 UncoveredArgHandler UncoveredArg;
7790 std::optional<unsigned> CallerParamIdx;
7792 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7793 firstDataArg,
Type, CallType,
7794 true, CheckedVarArgs, UncoveredArg,
7795 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7798 if (UncoveredArg.hasUncoveredArg()) {
7799 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7800 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7801 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7804 if (CT != SLCT_NotALiteral)
7806 return CT == SLCT_CheckedLiteral;
7812 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7818 this, Args, APK, ReferenceFormatString, format_idx,
7819 firstDataArg,
Type, *CallerParamIdx, Loc))
7829 if (Args.size() == firstDataArg) {
7830 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7838 Diag(FormatLoc, diag::note_format_security_fixit)
7842 Diag(FormatLoc, diag::note_format_security_fixit)
7847 Diag(FormatLoc, diag::warn_format_nonliteral)
7858 const FormatStringLiteral *FExpr;
7859 const Expr *OrigFormatExpr;
7861 const unsigned FirstDataArg;
7862 const unsigned NumDataArgs;
7865 ArrayRef<const Expr *> Args;
7867 llvm::SmallBitVector CoveredArgs;
7868 bool usesPositionalArgs =
false;
7869 bool atFirstArg =
true;
7870 bool inFunctionCall;
7872 llvm::SmallBitVector &CheckedVarArgs;
7873 UncoveredArgHandler &UncoveredArg;
7876 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7878 unsigned firstDataArg,
unsigned numDataArgs,
7880 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7882 llvm::SmallBitVector &CheckedVarArgs,
7883 UncoveredArgHandler &UncoveredArg)
7884 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7885 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7886 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7887 inFunctionCall(inFunctionCall), CallType(callType),
7888 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7889 CoveredArgs.resize(numDataArgs);
7890 CoveredArgs.reset();
7893 bool HasFormatArguments()
const {
7898 void DoneProcessing();
7900 void HandleIncompleteSpecifier(
const char *startSpecifier,
7901 unsigned specifierLen)
override;
7903 void HandleInvalidLengthModifier(
7904 const analyze_format_string::FormatSpecifier &FS,
7905 const analyze_format_string::ConversionSpecifier &CS,
7906 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
7908 void HandleNonStandardLengthModifier(
7909 const analyze_format_string::FormatSpecifier &FS,
7910 const char *startSpecifier,
unsigned specifierLen);
7912 void HandleNonStandardConversionSpecifier(
7913 const analyze_format_string::ConversionSpecifier &CS,
7914 const char *startSpecifier,
unsigned specifierLen);
7916 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7918 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
7921 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7923 void HandleNullChar(
const char *nullCharacter)
override;
7925 template <
typename Range>
7927 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7928 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7929 bool IsStringLocation, Range StringRange,
7930 ArrayRef<FixItHint> Fixit = {});
7933 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7934 const char *startSpec,
7935 unsigned specifierLen,
7936 const char *csStart,
unsigned csLen);
7938 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7939 const char *startSpec,
7940 unsigned specifierLen);
7942 SourceRange getFormatStringRange();
7943 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7944 unsigned specifierLen);
7945 SourceLocation getLocationOfByte(
const char *x);
7947 const Expr *getDataArg(
unsigned i)
const;
7949 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7950 const analyze_format_string::ConversionSpecifier &CS,
7951 const char *startSpecifier,
unsigned specifierLen,
7954 template <
typename Range>
7955 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7956 bool IsStringLocation, Range StringRange,
7957 ArrayRef<FixItHint> Fixit = {});
7962SourceRange CheckFormatHandler::getFormatStringRange() {
7967CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
7968 unsigned specifierLen) {
7970 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7978SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7983void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7984 unsigned specifierLen) {
7985 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7986 getLocationOfByte(startSpecifier),
7988 getSpecifierRange(startSpecifier, specifierLen));
7991void CheckFormatHandler::HandleInvalidLengthModifier(
7994 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8006 getSpecifierRange(startSpecifier, specifierLen));
8008 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8009 << FixedLM->toString()
8014 if (DiagID == diag::warn_format_nonsensical_length)
8020 getSpecifierRange(startSpecifier, specifierLen), Hint);
8024void CheckFormatHandler::HandleNonStandardLengthModifier(
8026 const char *startSpecifier,
unsigned specifierLen) {
8035 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8039 getSpecifierRange(startSpecifier, specifierLen));
8041 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8042 << FixedLM->toString()
8046 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8050 getSpecifierRange(startSpecifier, specifierLen));
8054void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8056 const char *startSpecifier,
unsigned specifierLen) {
8062 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8066 getSpecifierRange(startSpecifier, specifierLen));
8069 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8070 << FixedCS->toString()
8073 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8077 getSpecifierRange(startSpecifier, specifierLen));
8081void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8083 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8084 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8085 getLocationOfByte(startPos),
8087 getSpecifierRange(startPos, posLen));
8090void CheckFormatHandler::HandleInvalidPosition(
8091 const char *startSpecifier,
unsigned specifierLen,
8094 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8095 EmitFormatDiagnostic(
8096 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8097 getLocationOfByte(startSpecifier),
true,
8098 getSpecifierRange(startSpecifier, specifierLen));
8101void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8105 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8106 getLocationOfByte(startPos),
8108 getSpecifierRange(startPos, posLen));
8111void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8114 EmitFormatDiagnostic(
8115 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8116 getLocationOfByte(nullCharacter),
true,
8117 getFormatStringRange());
8123const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8124 return Args[FirstDataArg + i];
8127void CheckFormatHandler::DoneProcessing() {
8130 if (HasFormatArguments()) {
8133 signed notCoveredArg = CoveredArgs.find_first();
8134 if (notCoveredArg >= 0) {
8135 assert((
unsigned)notCoveredArg < NumDataArgs);
8136 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8138 UncoveredArg.setAllCovered();
8143void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8144 const Expr *ArgExpr) {
8145 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8156 for (
auto E : DiagnosticExprs)
8159 CheckFormatHandler::EmitFormatDiagnostic(
8160 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8164bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8166 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8167 bool keepGoing =
true;
8168 if (argIndex < NumDataArgs) {
8171 CoveredArgs.set(argIndex);
8186 std::string CodePointStr;
8187 if (!llvm::sys::locale::isPrint(*csStart)) {
8188 llvm::UTF32 CodePoint;
8189 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8190 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8191 llvm::ConversionResult
Result =
8192 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8194 if (
Result != llvm::conversionOK) {
8195 unsigned char FirstChar = *csStart;
8196 CodePoint = (llvm::UTF32)FirstChar;
8199 llvm::raw_string_ostream
OS(CodePointStr);
8200 if (CodePoint < 256)
8201 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8202 else if (CodePoint <= 0xFFFF)
8203 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8205 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8209 EmitFormatDiagnostic(
8210 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8211 true, getSpecifierRange(startSpec, specifierLen));
8216void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8217 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8218 EmitFormatDiagnostic(
8219 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8220 true, getSpecifierRange(startSpec, specifierLen));
8223bool CheckFormatHandler::CheckNumArgs(
8226 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8228 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8231 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8232 << (argIndex + 1) << NumDataArgs)
8233 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8234 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8236 getSpecifierRange(startSpecifier, specifierLen));
8240 UncoveredArg.setAllCovered();
8246template <
typename Range>
8249 bool IsStringLocation,
8252 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8253 IsStringLocation, StringRange, FixIt);
8283template <
typename Range>
8284void CheckFormatHandler::EmitFormatDiagnostic(
8285 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8288 if (InFunctionCall) {
8293 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8297 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8298 diag::note_format_string_defined);
8300 Note << StringRange;
8309class CheckPrintfHandler :
public CheckFormatHandler {
8311 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8313 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8315 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8317 llvm::SmallBitVector &CheckedVarArgs,
8318 UncoveredArgHandler &UncoveredArg)
8319 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8320 numDataArgs, beg, APK, Args, formatIdx,
8321 inFunctionCall, CallType, CheckedVarArgs,
8324 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8327 bool allowsObjCArg()
const {
8328 return FSType == FormatStringType::NSString ||
8329 FSType == FormatStringType::OSLog ||
8330 FSType == FormatStringType::OSTrace;
8333 bool HandleInvalidPrintfConversionSpecifier(
8334 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8335 unsigned specifierLen)
override;
8337 void handleInvalidMaskType(StringRef MaskType)
override;
8339 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8340 const char *startSpecifier,
unsigned specifierLen,
8341 const TargetInfo &
Target)
override;
8342 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8343 const char *StartSpecifier,
unsigned SpecifierLen,
8346 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8347 unsigned k,
const char *startSpecifier,
8348 unsigned specifierLen);
8349 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8350 const analyze_printf::OptionalAmount &Amt,
8351 unsigned type,
const char *startSpecifier,
8352 unsigned specifierLen);
8353 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8354 const analyze_printf::OptionalFlag &flag,
8355 const char *startSpecifier,
unsigned specifierLen);
8356 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8357 const analyze_printf::OptionalFlag &ignoredFlag,
8358 const analyze_printf::OptionalFlag &flag,
8359 const char *startSpecifier,
unsigned specifierLen);
8360 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8362 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8363 unsigned flagLen)
override;
8365 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8366 unsigned flagLen)
override;
8369 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8370 const char *flagsEnd,
8371 const char *conversionPosition)
override;
8376class EquatableFormatArgument {
8378 enum SpecifierSensitivity :
unsigned {
8385 enum FormatArgumentRole :
unsigned {
8393 analyze_format_string::ArgType ArgType;
8395 StringRef SpecifierLetter;
8396 CharSourceRange
Range;
8397 SourceLocation ElementLoc;
8398 FormatArgumentRole
Role : 2;
8399 SpecifierSensitivity Sensitivity : 2;
8400 unsigned Position : 14;
8401 unsigned ModifierFor : 14;
8403 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8404 bool InFunctionCall)
const;
8407 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8409 StringRef SpecifierLetter,
8410 analyze_format_string::ArgType ArgType,
8411 FormatArgumentRole
Role,
8412 SpecifierSensitivity Sensitivity,
unsigned Position,
8413 unsigned ModifierFor)
8414 : ArgType(ArgType), LengthMod(LengthMod),
8415 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8416 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8417 ModifierFor(ModifierFor) {}
8419 unsigned getPosition()
const {
return Position; }
8420 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8422 analyze_format_string::LengthModifier getLengthModifier()
const {
8423 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
8425 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8427 std::string buildFormatSpecifier()
const {
8429 llvm::raw_string_ostream(result)
8430 << getLengthModifier().toString() << SpecifierLetter;
8434 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8435 const Expr *FmtExpr,
bool InFunctionCall)
const;
8439class DecomposePrintfHandler :
public CheckPrintfHandler {
8440 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8443 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8444 const Expr *origFormatExpr,
8446 unsigned numDataArgs,
bool isObjC,
const char *beg,
8448 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8450 llvm::SmallBitVector &CheckedVarArgs,
8451 UncoveredArgHandler &UncoveredArg,
8452 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8453 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8454 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8455 inFunctionCall, CallType, CheckedVarArgs,
8457 Specs(Specs), HadError(
false) {}
8461 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8463 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8465 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8466 const char *startSpecifier,
8467 unsigned specifierLen,
8468 const TargetInfo &
Target)
override;
8473bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8475 unsigned specifierLen) {
8479 return HandleInvalidConversionSpecifier(
8484void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8485 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8493 return T->isRecordType() || T->isComplexType();
8496bool CheckPrintfHandler::HandleAmount(
8498 const char *startSpecifier,
unsigned specifierLen) {
8500 if (HasFormatArguments()) {
8502 if (argIndex >= NumDataArgs) {
8503 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8507 getSpecifierRange(startSpecifier, specifierLen));
8517 CoveredArgs.set(argIndex);
8518 const Expr *Arg = getDataArg(argIndex);
8529 ? diag::err_printf_asterisk_wrong_type
8530 : diag::warn_printf_asterisk_wrong_type;
8531 EmitFormatDiagnostic(S.
PDiag(DiagID)
8536 getSpecifierRange(startSpecifier, specifierLen));
8546void CheckPrintfHandler::HandleInvalidAmount(
8549 const char *startSpecifier,
unsigned specifierLen) {
8559 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8563 getSpecifierRange(startSpecifier, specifierLen), fixit);
8568 const char *startSpecifier,
8569 unsigned specifierLen) {
8573 EmitFormatDiagnostic(
8574 S.
PDiag(diag::warn_printf_nonsensical_flag)
8578 getSpecifierRange(startSpecifier, specifierLen),
8582void CheckPrintfHandler::HandleIgnoredFlag(
8586 unsigned specifierLen) {
8588 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8592 getSpecifierRange(startSpecifier, specifierLen),
8594 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8597void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8600 EmitFormatDiagnostic(
8601 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8602 true, getSpecifierRange(startFlag, flagLen));
8605void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8608 auto Range = getSpecifierRange(startFlag, flagLen);
8609 StringRef flag(startFlag, flagLen);
8610 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8611 getLocationOfByte(startFlag),
8616void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8617 const char *flagsStart,
const char *flagsEnd,
8618 const char *conversionPosition) {
8620 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8621 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8622 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8623 getLocationOfByte(conversionPosition),
8629 const Expr *FmtExpr,
8630 bool InFunctionCall)
const {
8631 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8632 ElementLoc,
true, Range);
8635bool EquatableFormatArgument::VerifyCompatible(
8636 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8637 bool InFunctionCall)
const {
8642 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8643 FmtExpr, InFunctionCall);
8644 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8648 if (
Role != FAR_Data) {
8649 if (ModifierFor !=
Other.ModifierFor) {
8652 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8653 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8654 FmtExpr, InFunctionCall);
8655 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8661 bool HadError =
false;
8662 if (Sensitivity !=
Other.Sensitivity) {
8665 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8666 << Sensitivity <<
Other.Sensitivity,
8667 FmtExpr, InFunctionCall);
8668 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8669 << 0 <<
Other.Range;
8672 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8676 case MK::MatchPromotion:
8680 case MK::NoMatchTypeConfusion:
8681 case MK::NoMatchPromotionTypeConfusion:
8683 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8684 << buildFormatSpecifier()
8685 <<
Other.buildFormatSpecifier(),
8686 FmtExpr, InFunctionCall);
8687 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8688 << 0 <<
Other.Range;
8691 case MK::NoMatchPedantic:
8693 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8694 << buildFormatSpecifier()
8695 <<
Other.buildFormatSpecifier(),
8696 FmtExpr, InFunctionCall);
8697 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8698 << 0 <<
Other.Range;
8701 case MK::NoMatchSignedness:
8703 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8704 << buildFormatSpecifier()
8705 <<
Other.buildFormatSpecifier(),
8706 FmtExpr, InFunctionCall);
8707 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8708 << 0 <<
Other.Range;
8714bool DecomposePrintfHandler::GetSpecifiers(
8715 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8718 StringRef
Data = FSL->getString();
8719 const char *Str =
Data.data();
8720 llvm::SmallBitVector BV;
8721 UncoveredArgHandler UA;
8722 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8723 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8735 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8736 const EquatableFormatArgument &B) {
8737 return A.getPosition() < B.getPosition();
8742bool DecomposePrintfHandler::HandlePrintfSpecifier(
8745 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8760 const unsigned Unset = ~0;
8761 unsigned FieldWidthIndex = Unset;
8762 unsigned PrecisionIndex = Unset;
8766 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8767 FieldWidthIndex = Specs.size();
8769 getSpecifierRange(startSpecifier, specifierLen),
8770 getLocationOfByte(FieldWidth.getStart()),
8772 FieldWidth.getArgType(S.
Context),
8773 EquatableFormatArgument::FAR_FieldWidth,
8774 EquatableFormatArgument::SS_None,
8775 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
8781 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8782 PrecisionIndex = Specs.size();
8784 getSpecifierRange(startSpecifier, specifierLen),
8785 getLocationOfByte(Precision.getStart()),
8787 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8788 EquatableFormatArgument::SS_None,
8789 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8795 unsigned SpecIndex =
8797 if (FieldWidthIndex != Unset)
8798 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8799 if (PrecisionIndex != Unset)
8800 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8802 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8804 Sensitivity = EquatableFormatArgument::SS_Private;
8806 Sensitivity = EquatableFormatArgument::SS_Public;
8808 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8810 Sensitivity = EquatableFormatArgument::SS_None;
8813 getSpecifierRange(startSpecifier, specifierLen),
8816 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8821 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8826 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8827 SpecIndex + 1, SpecIndex);
8835template<
typename MemberKind>
8846 R.suppressDiagnostics();
8853 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8868 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8870 if ((*MI)->getMinRequiredArguments() == 0)
8878bool CheckPrintfHandler::checkForCStrMembers(
8885 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8888 if (
Method->getMinRequiredArguments() == 0 &&
8901bool CheckPrintfHandler::HandlePrintfSpecifier(
8914 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8915 startSpecifier, specifierLen);
8927 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
8932 if (!CS.consumesDataArgument()) {
8940 if (argIndex < NumDataArgs) {
8944 CoveredArgs.set(argIndex);
8951 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8954 if (HasFormatArguments()) {
8956 CoveredArgs.set(argIndex + 1);
8959 const Expr *Ex = getDataArg(argIndex);
8963 : ArgType::CPointerTy;
8965 EmitFormatDiagnostic(
8966 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8970 getSpecifierRange(startSpecifier, specifierLen));
8973 Ex = getDataArg(argIndex + 1);
8976 EmitFormatDiagnostic(
8977 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8981 getSpecifierRange(startSpecifier, specifierLen));
8988 if (!allowsObjCArg() && CS.isObjCArg()) {
8989 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8996 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9003 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9004 getLocationOfByte(CS.getStart()),
9006 getSpecifierRange(startSpecifier, specifierLen));
9016 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9023 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9027 getSpecifierRange(startSpecifier, specifierLen));
9030 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9034 getSpecifierRange(startSpecifier, specifierLen));
9038 const llvm::Triple &Triple =
Target.getTriple();
9040 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9041 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9042 getLocationOfByte(CS.getStart()),
9044 getSpecifierRange(startSpecifier, specifierLen));
9050 startSpecifier, specifierLen);
9056 startSpecifier, specifierLen);
9062 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9063 getLocationOfByte(startSpecifier),
9065 getSpecifierRange(startSpecifier, specifierLen));
9074 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9076 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9085 startSpecifier, specifierLen);
9088 startSpecifier, specifierLen);
9093 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9094 diag::warn_format_nonsensical_length);
9096 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9098 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9099 diag::warn_format_non_standard_conversion_spec);
9102 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9105 if (!HasFormatArguments())
9108 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9111 const Expr *Arg = getDataArg(argIndex);
9115 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9127 case Stmt::ArraySubscriptExprClass:
9128 case Stmt::CallExprClass:
9129 case Stmt::CharacterLiteralClass:
9130 case Stmt::CXXBoolLiteralExprClass:
9131 case Stmt::DeclRefExprClass:
9132 case Stmt::FloatingLiteralClass:
9133 case Stmt::IntegerLiteralClass:
9134 case Stmt::MemberExprClass:
9135 case Stmt::ObjCArrayLiteralClass:
9136 case Stmt::ObjCBoolLiteralExprClass:
9137 case Stmt::ObjCBoxedExprClass:
9138 case Stmt::ObjCDictionaryLiteralClass:
9139 case Stmt::ObjCEncodeExprClass:
9140 case Stmt::ObjCIvarRefExprClass:
9141 case Stmt::ObjCMessageExprClass:
9142 case Stmt::ObjCPropertyRefExprClass:
9143 case Stmt::ObjCStringLiteralClass:
9144 case Stmt::ObjCSubscriptRefExprClass:
9145 case Stmt::ParenExprClass:
9146 case Stmt::StringLiteralClass:
9147 case Stmt::UnaryOperatorClass:
9154static std::pair<QualType, StringRef>
9160 StringRef Name = UserTy->getDecl()->getName();
9161 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9162 .Case(
"CFIndex", Context.getNSIntegerType())
9163 .Case(
"NSInteger", Context.getNSIntegerType())
9164 .Case(
"NSUInteger", Context.getNSUIntegerType())
9165 .Case(
"SInt32", Context.IntTy)
9166 .Case(
"UInt32", Context.UnsignedIntTy)
9170 return std::make_pair(CastTy, Name);
9172 TyTy = UserTy->desugar();
9176 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9186 StringRef TrueName, FalseName;
9189 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9191 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9193 if (TrueTy == FalseTy)
9194 return std::make_pair(TrueTy, TrueName);
9195 else if (TrueTy.
isNull())
9196 return std::make_pair(FalseTy, FalseName);
9197 else if (FalseTy.
isNull())
9198 return std::make_pair(TrueTy, TrueName);
9201 return std::make_pair(
QualType(), StringRef());
9220 From = VecTy->getElementType();
9222 To = VecTy->getElementType();
9233 diag::warn_format_conversion_argument_type_mismatch_signedness,
9237 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9244bool CheckPrintfHandler::checkFormatExpr(
9246 unsigned SpecifierLen,
const Expr *E) {
9257 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9258 ExprTy = TET->getUnderlyingExpr()->getType();
9261 if (
const OverflowBehaviorType *OBT =
9263 ExprTy = OBT->getUnderlyingType();
9277 getSpecifierRange(StartSpecifier, SpecifierLen);
9279 llvm::raw_svector_ostream os(FSString);
9281 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9292 getSpecifierRange(StartSpecifier, SpecifierLen);
9293 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9303 if (
Match == ArgType::Match)
9307 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9316 E = ICE->getSubExpr();
9326 if (OrigMatch == ArgType::NoMatchSignedness &&
9327 ImplicitMatch != ArgType::NoMatchSignedness)
9334 if (ImplicitMatch == ArgType::Match)
9352 if (
Match == ArgType::MatchPromotion)
9356 if (
Match == ArgType::MatchPromotion) {
9360 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9361 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9365 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9366 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9367 Match = ImplicitMatch;
9368 assert(
Match != ArgType::MatchPromotion);
9371 bool IsEnum =
false;
9372 bool IsScopedEnum =
false;
9375 IntendedTy = ED->getIntegerType();
9376 if (!ED->isScoped()) {
9377 ExprTy = IntendedTy;
9382 IsScopedEnum =
true;
9389 if (isObjCContext() &&
9400 const llvm::APInt &
V = IL->getValue();
9410 if (TD->getUnderlyingType() == IntendedTy)
9420 bool ShouldNotPrintDirectly =
false;
9421 StringRef CastTyName;
9424 std::tie(CastTy, CastTyName) =
9430 if (!IsScopedEnum &&
9431 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9435 IntendedTy = CastTy;
9436 ShouldNotPrintDirectly =
true;
9441 PrintfSpecifier fixedFS = FS;
9448 llvm::raw_svector_ostream os(buf);
9451 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9453 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9459 llvm_unreachable(
"expected non-matching");
9461 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9464 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9467 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9470 Diag = diag::warn_format_conversion_argument_type_mismatch;
9491 llvm::raw_svector_ostream CastFix(CastBuf);
9492 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9494 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9500 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9505 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9527 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9533 Name = TypedefTy->getDecl()->getName();
9537 ? diag::warn_format_argument_needs_cast_pedantic
9538 : diag::warn_format_argument_needs_cast;
9539 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9550 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9551 : diag::warn_format_conversion_argument_type_mismatch;
9553 EmitFormatDiagnostic(
9561 getSpecifierRange(StartSpecifier, SpecifierLen);
9565 bool EmitTypeMismatch =
false;
9574 llvm_unreachable(
"expected non-matching");
9576 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9579 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9582 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9586 ? diag::err_format_conversion_argument_type_mismatch
9587 : diag::warn_format_conversion_argument_type_mismatch;
9591 EmitFormatDiagnostic(
9600 EmitTypeMismatch =
true;
9602 EmitFormatDiagnostic(
9603 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9604 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9608 checkForCStrMembers(AT, E);
9614 EmitTypeMismatch =
true;
9616 EmitFormatDiagnostic(
9617 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9618 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9631 if (EmitTypeMismatch) {
9637 EmitFormatDiagnostic(
9638 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9644 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9645 "format string specifier index out of range");
9646 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9656class CheckScanfHandler :
public CheckFormatHandler {
9658 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9660 unsigned firstDataArg,
unsigned numDataArgs,
9662 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9664 llvm::SmallBitVector &CheckedVarArgs,
9665 UncoveredArgHandler &UncoveredArg)
9666 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9667 numDataArgs, beg, APK, Args, formatIdx,
9668 inFunctionCall, CallType, CheckedVarArgs,
9671 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9672 const char *startSpecifier,
9673 unsigned specifierLen)
override;
9676 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9677 const char *startSpecifier,
9678 unsigned specifierLen)
override;
9680 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9685void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9687 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9688 getLocationOfByte(end),
true,
9689 getSpecifierRange(start, end - start));
9692bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9694 unsigned specifierLen) {
9698 return HandleInvalidConversionSpecifier(
9703bool CheckScanfHandler::HandleScanfSpecifier(
9705 unsigned specifierLen) {
9718 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9719 startSpecifier, specifierLen);
9730 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9745 if (argIndex < NumDataArgs) {
9749 CoveredArgs.set(argIndex);
9755 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9756 diag::warn_format_nonsensical_length);
9758 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9760 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9761 diag::warn_format_non_standard_conversion_spec);
9764 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9767 if (!HasFormatArguments())
9770 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9774 const Expr *Ex = getDataArg(argIndex);
9792 ScanfSpecifier fixedFS = FS;
9797 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9799 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9800 : diag::warn_format_conversion_argument_type_mismatch;
9805 llvm::raw_svector_ostream os(buf);
9808 EmitFormatDiagnostic(
9813 getSpecifierRange(startSpecifier, specifierLen),
9815 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9822 getSpecifierRange(startSpecifier, specifierLen));
9832 const Expr *FmtExpr,
bool InFunctionCall) {
9833 bool HadError =
false;
9834 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9835 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9836 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9848 for (; FmtIter < FmtEnd; ++FmtIter) {
9852 if (FmtIter->getPosition() < RefIter->getPosition())
9856 if (FmtIter->getPosition() > RefIter->getPosition())
9860 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9864 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9865 return Arg.getPosition() != RefIter->getPosition();
9869 if (FmtIter < FmtEnd) {
9870 CheckFormatHandler::EmitFormatDiagnostic(
9871 S, InFunctionCall, FmtExpr,
9872 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9873 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9874 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9875 }
else if (RefIter < RefEnd) {
9876 CheckFormatHandler::EmitFormatDiagnostic(
9877 S, InFunctionCall, FmtExpr,
9878 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9881 << 1 << RefIter->getSourceRange();
9887 Sema &S,
const FormatStringLiteral *FExpr,
9892 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9893 bool IgnoreStringsWithoutSpecifiers) {
9895 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9896 CheckFormatHandler::EmitFormatDiagnostic(
9897 S, inFunctionCall, Args[format_idx],
9898 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9904 StringRef StrRef = FExpr->getString();
9905 const char *Str = StrRef.data();
9909 assert(T &&
"String literal not of constant array type!");
9910 size_t TypeSize = T->getZExtSize();
9911 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9912 const unsigned numDataArgs = Args.size() - firstDataArg;
9914 if (IgnoreStringsWithoutSpecifiers &&
9921 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9922 CheckFormatHandler::EmitFormatDiagnostic(
9923 S, inFunctionCall, Args[format_idx],
9924 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9925 FExpr->getBeginLoc(),
9931 if (StrLen == 0 && numDataArgs > 0) {
9932 CheckFormatHandler::EmitFormatDiagnostic(
9933 S, inFunctionCall, Args[format_idx],
9934 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9945 if (ReferenceFormatString ==
nullptr) {
9946 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9947 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9948 inFunctionCall, CallType, CheckedVarArgs,
9958 Type, ReferenceFormatString, FExpr->getFormatString(),
9959 inFunctionCall ?
nullptr : Args[format_idx]);
9962 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9963 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9964 CallType, CheckedVarArgs, UncoveredArg);
9984 FormatStringLiteral RefLit = AuthoritativeFormatString;
9985 FormatStringLiteral TestLit = TestedFormatString;
9987 bool DiagAtStringLiteral;
9988 if (FunctionCallArg) {
9989 Arg = FunctionCallArg;
9990 DiagAtStringLiteral =
false;
9992 Arg = TestedFormatString;
9993 DiagAtStringLiteral =
true;
9995 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9996 AuthoritativeFormatString,
Type,
9997 IsObjC,
true, RefArgs) &&
9998 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9999 DiagAtStringLiteral, FmtArgs)) {
10001 TestedFormatString, FmtArgs, Arg,
10002 DiagAtStringLiteral);
10015 FormatStringLiteral RefLit = Str;
10019 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10028 bool HadError =
false;
10029 auto Iter = Args.begin();
10030 auto End = Args.end();
10031 while (Iter != End) {
10032 const auto &FirstInGroup = *Iter;
10034 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10036 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10045 const char *Str = StrRef.data();
10048 assert(T &&
"String literal not of constant array type!");
10049 size_t TypeSize = T->getZExtSize();
10050 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10060 switch (AbsFunction) {
10064 case Builtin::BI__builtin_abs:
10065 return Builtin::BI__builtin_labs;
10066 case Builtin::BI__builtin_labs:
10067 return Builtin::BI__builtin_llabs;
10068 case Builtin::BI__builtin_llabs:
10071 case Builtin::BI__builtin_fabsf:
10072 return Builtin::BI__builtin_fabs;
10073 case Builtin::BI__builtin_fabs:
10074 return Builtin::BI__builtin_fabsl;
10075 case Builtin::BI__builtin_fabsl:
10078 case Builtin::BI__builtin_cabsf:
10079 return Builtin::BI__builtin_cabs;
10080 case Builtin::BI__builtin_cabs:
10081 return Builtin::BI__builtin_cabsl;
10082 case Builtin::BI__builtin_cabsl:
10085 case Builtin::BIabs:
10086 return Builtin::BIlabs;
10087 case Builtin::BIlabs:
10088 return Builtin::BIllabs;
10089 case Builtin::BIllabs:
10092 case Builtin::BIfabsf:
10093 return Builtin::BIfabs;
10094 case Builtin::BIfabs:
10095 return Builtin::BIfabsl;
10096 case Builtin::BIfabsl:
10099 case Builtin::BIcabsf:
10100 return Builtin::BIcabs;
10101 case Builtin::BIcabs:
10102 return Builtin::BIcabsl;
10103 case Builtin::BIcabsl:
10110 unsigned AbsType) {
10132 unsigned AbsFunctionKind) {
10133 unsigned BestKind = 0;
10134 uint64_t ArgSize = Context.getTypeSize(ArgType);
10135 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10138 if (Context.getTypeSize(ParamType) >= ArgSize) {
10141 else if (Context.hasSameType(ParamType, ArgType)) {
10157 if (T->isIntegralOrEnumerationType())
10159 if (T->isRealFloatingType())
10161 if (T->isAnyComplexType())
10164 llvm_unreachable(
"Type not integer, floating, or complex");
10171 switch (ValueKind) {
10176 case Builtin::BI__builtin_fabsf:
10177 case Builtin::BI__builtin_fabs:
10178 case Builtin::BI__builtin_fabsl:
10179 case Builtin::BI__builtin_cabsf:
10180 case Builtin::BI__builtin_cabs:
10181 case Builtin::BI__builtin_cabsl:
10182 return Builtin::BI__builtin_abs;
10183 case Builtin::BIfabsf:
10184 case Builtin::BIfabs:
10185 case Builtin::BIfabsl:
10186 case Builtin::BIcabsf:
10187 case Builtin::BIcabs:
10188 case Builtin::BIcabsl:
10189 return Builtin::BIabs;
10195 case Builtin::BI__builtin_abs:
10196 case Builtin::BI__builtin_labs:
10197 case Builtin::BI__builtin_llabs:
10198 case Builtin::BI__builtin_cabsf:
10199 case Builtin::BI__builtin_cabs:
10200 case Builtin::BI__builtin_cabsl:
10201 return Builtin::BI__builtin_fabsf;
10202 case Builtin::BIabs:
10203 case Builtin::BIlabs:
10204 case Builtin::BIllabs:
10205 case Builtin::BIcabsf:
10206 case Builtin::BIcabs:
10207 case Builtin::BIcabsl:
10208 return Builtin::BIfabsf;
10214 case Builtin::BI__builtin_abs:
10215 case Builtin::BI__builtin_labs:
10216 case Builtin::BI__builtin_llabs:
10217 case Builtin::BI__builtin_fabsf:
10218 case Builtin::BI__builtin_fabs:
10219 case Builtin::BI__builtin_fabsl:
10220 return Builtin::BI__builtin_cabsf;
10221 case Builtin::BIabs:
10222 case Builtin::BIlabs:
10223 case Builtin::BIllabs:
10224 case Builtin::BIfabsf:
10225 case Builtin::BIfabs:
10226 case Builtin::BIfabsl:
10227 return Builtin::BIcabsf;
10230 llvm_unreachable(
"Unable to convert function");
10241 case Builtin::BI__builtin_abs:
10242 case Builtin::BI__builtin_fabs:
10243 case Builtin::BI__builtin_fabsf:
10244 case Builtin::BI__builtin_fabsl:
10245 case Builtin::BI__builtin_labs:
10246 case Builtin::BI__builtin_llabs:
10247 case Builtin::BI__builtin_cabs:
10248 case Builtin::BI__builtin_cabsf:
10249 case Builtin::BI__builtin_cabsl:
10250 case Builtin::BIabs:
10251 case Builtin::BIlabs:
10252 case Builtin::BIllabs:
10253 case Builtin::BIfabs:
10254 case Builtin::BIfabsf:
10255 case Builtin::BIfabsl:
10256 case Builtin::BIcabs:
10257 case Builtin::BIcabsf:
10258 case Builtin::BIcabsl:
10261 llvm_unreachable(
"Unknown Builtin type");
10267 unsigned AbsKind,
QualType ArgType) {
10268 bool EmitHeaderHint =
true;
10269 const char *HeaderName =
nullptr;
10270 std::string FunctionName;
10271 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10272 FunctionName =
"std::abs";
10273 if (ArgType->isIntegralOrEnumerationType()) {
10274 HeaderName =
"cstdlib";
10275 }
else if (ArgType->isRealFloatingType()) {
10276 HeaderName =
"cmath";
10278 llvm_unreachable(
"Invalid Type");
10284 R.suppressDiagnostics();
10287 for (
const auto *I : R) {
10290 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10292 FDecl = dyn_cast<FunctionDecl>(I);
10307 EmitHeaderHint =
false;
10319 R.suppressDiagnostics();
10322 if (R.isSingleResult()) {
10323 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10325 EmitHeaderHint =
false;
10329 }
else if (!R.empty()) {
10335 S.
Diag(Loc, diag::note_replace_abs_function)
10341 if (!EmitHeaderHint)
10344 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10348template <std::
size_t StrLen>
10350 const char (&Str)[StrLen]) {
10363 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10364 return llvm::is_contained(names, calleeName);
10369 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10370 "__builtin_nanf16",
"__builtin_nanf128"});
10372 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10373 "__builtin_inff16",
"__builtin_inff128"});
10375 llvm_unreachable(
"unknown MathCheck");
10379 if (FDecl->
getName() !=
"infinity")
10382 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10384 if (RDecl->
getName() !=
"numeric_limits")
10401 if (FPO.getNoHonorNaNs() &&
10404 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10405 << 1 << 0 <<
Call->getSourceRange();
10409 if (FPO.getNoHonorInfs() &&
10413 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10414 << 0 << 0 <<
Call->getSourceRange();
10418void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10420 if (
Call->getNumArgs() != 1)
10425 if (AbsKind == 0 && !IsStdAbs)
10428 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10429 QualType ParamType =
Call->getArg(0)->getType();
10434 std::string FunctionName =
10435 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10436 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10437 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10466 if (ArgValueKind == ParamValueKind) {
10467 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10471 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10472 << FDecl << ArgType << ParamType;
10474 if (NewAbsKind == 0)
10478 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10487 if (NewAbsKind == 0)
10490 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10491 << FDecl << ParamValueKind << ArgValueKind;
10494 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10500 if (!
Call || !FDecl)
return;
10504 if (
Call->getExprLoc().isMacroID())
return;
10507 if (
Call->getNumArgs() != 2)
return;
10510 if (!ArgList)
return;
10511 if (ArgList->size() != 1)
return;
10514 const auto& TA = ArgList->
get(0);
10516 QualType ArgType = TA.getAsType();
10520 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10521 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10522 if (!MTE)
return false;
10523 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10524 if (!
Num)
return false;
10525 if (
Num->getValue() != 0)
return false;
10529 const Expr *FirstArg =
Call->getArg(0);
10530 const Expr *SecondArg =
Call->getArg(1);
10531 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10532 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10535 if (IsFirstArgZero == IsSecondArgZero)
return;
10540 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10542 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10543 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10546 SourceRange RemovalRange;
10547 if (IsFirstArgZero) {
10548 RemovalRange = SourceRange(FirstRange.
getBegin(),
10555 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10570 const auto *Size = dyn_cast<BinaryOperator>(E);
10575 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10579 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10580 << SizeRange << FnName;
10581 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10586 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10597 bool &IsContained) {
10600 IsContained =
false;
10613 for (
auto *FD : RD->
fields()) {
10617 IsContained =
true;
10618 return ContainedRD;
10626 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10627 if (Unary->getKind() == UETT_SizeOf)
10636 if (!
SizeOf->isArgumentType())
10637 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10644 return SizeOf->getTypeOfArgument();
10650struct SearchNonTrivialToInitializeField
10653 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10655 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10658 SourceLocation SL) {
10659 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10660 asDerived().visitArray(PDIK, AT, SL);
10664 Super::visitWithKind(PDIK, FT, SL);
10667 void visitARCStrong(QualType FT, SourceLocation SL) {
10670 void visitARCWeak(QualType FT, SourceLocation SL) {
10673 void visitStruct(QualType FT, SourceLocation SL) {
10678 const ArrayType *AT, SourceLocation SL) {
10679 visit(getContext().getBaseElementType(AT), SL);
10681 void visitTrivial(QualType FT, SourceLocation SL) {}
10683 static void diag(QualType RT,
const Expr *E, Sema &S) {
10684 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10693struct SearchNonTrivialToCopyField
10695 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10697 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10700 SourceLocation SL) {
10701 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10702 asDerived().visitArray(PCK, AT, SL);
10706 Super::visitWithKind(PCK, FT, SL);
10709 void visitARCStrong(QualType FT, SourceLocation SL) {
10712 void visitARCWeak(QualType FT, SourceLocation SL) {
10715 void visitPtrAuth(QualType FT, SourceLocation SL) {
10718 void visitStruct(QualType FT, SourceLocation SL) {
10723 SourceLocation SL) {
10724 visit(getContext().getBaseElementType(AT), SL);
10727 SourceLocation SL) {}
10728 void visitTrivial(QualType FT, SourceLocation SL) {}
10729 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10731 static void diag(QualType RT,
const Expr *E, Sema &S) {
10732 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10747 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10748 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10772 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10774 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10775 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10781 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10784 const Expr *SizeArg =
10785 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10787 auto isLiteralZero = [](
const Expr *E) {
10797 if (isLiteralZero(SizeArg) &&
10804 if (BId == Builtin::BIbzero ||
10807 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10808 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10809 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10810 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10811 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10819 if (BId == Builtin::BImemset &&
10823 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10824 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10829void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10836 unsigned ExpectedNumArgs =
10837 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10838 if (
Call->getNumArgs() < ExpectedNumArgs)
10841 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10842 BId == Builtin::BIstrndup ? 1 : 2);
10844 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10848 Call->getBeginLoc(),
Call->getRParenLoc()))
10860 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10861 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10864 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10868 QualType DestTy = Dest->
getType();
10869 QualType PointeeTy;
10870 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10882 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
10888 if (SizeOfArgTy != QualType()) {
10890 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10892 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10893 << FnName << SizeOfArgTy << ArgIdx
10900 PointeeTy = DestTy;
10903 if (PointeeTy == QualType())
10908 if (
const CXXRecordDecl *ContainedRD =
10911 unsigned OperationType = 0;
10912 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10915 if (ArgIdx != 0 || IsCmp) {
10916 if (BId == Builtin::BImemcpy)
10918 else if(BId == Builtin::BImemmove)
10925 PDiag(diag::warn_dyn_class_memaccess)
10926 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10927 << IsContained << ContainedRD << OperationType
10928 <<
Call->getCallee()->getSourceRange());
10930 BId != Builtin::BImemset)
10933 PDiag(diag::warn_arc_object_memaccess)
10934 << ArgIdx << FnName << PointeeTy
10935 <<
Call->getCallee()->getSourceRange());
10942 bool NonTriviallyCopyableCXXRecord =
10946 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10949 PDiag(diag::warn_cstruct_memaccess)
10950 << ArgIdx << FnName << PointeeTy << 0);
10951 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10952 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10953 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10957 PDiag(diag::warn_cxxstruct_memaccess)
10958 << FnName << PointeeTy);
10959 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10962 PDiag(diag::warn_cstruct_memaccess)
10963 << ArgIdx << FnName << PointeeTy << 1);
10964 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10965 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10966 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10970 PDiag(diag::warn_cxxstruct_memaccess)
10971 << FnName << PointeeTy);
10980 PDiag(diag::note_bad_memaccess_silence)
10986bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
10988 llvm::FoldingSetNodeID SizeOfArgID;
10994 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10997 QualType DestTy = Dest->
getType();
10998 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11004 if (SizeOfArgID == llvm::FoldingSetNodeID())
11007 llvm::FoldingSetNodeID DestID;
11009 if (DestID == SizeOfArgID) {
11012 unsigned ActionIdx = 0;
11013 StringRef ReadableName = FnName->
getName();
11015 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11016 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11025 SourceLocation SL = SizeOfArg->
getExprLoc();
11030 if (
SM.isMacroArgExpansion(SL)) {
11032 SL =
SM.getSpellingLoc(SL);
11033 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
11035 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
11040 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11041 << ReadableName << PointeeTy << DestTy << DSR
11044 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11045 << ActionIdx << SSR);
11081 if (CAT->getZExtSize() <= 1)
11089void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11093 unsigned NumArgs =
Call->getNumArgs();
11094 if ((NumArgs != 3) && (NumArgs != 4))
11099 const Expr *CompareWithSrc =
nullptr;
11102 Call->getBeginLoc(),
Call->getRParenLoc()))
11107 CompareWithSrc = Ex;
11110 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11111 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11112 SizeCall->getNumArgs() == 1)
11117 if (!CompareWithSrc)
11124 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11128 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11129 if (!CompareWithSrcDRE ||
11133 const Expr *OriginalSizeArg =
Call->getArg(2);
11134 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11141 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11145 SmallString<128> sizeString;
11146 llvm::raw_svector_ostream
OS(sizeString);
11151 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11158 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11159 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11160 return D1->getDecl() == D2->getDecl();
11165 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11174void Sema::CheckStrncatArguments(
const CallExpr *CE,
11189 unsigned PatternType = 0;
11197 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11198 if (BE->getOpcode() == BO_Sub) {
11199 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11200 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11211 if (PatternType == 0)
11220 if (
SM.isMacroArgExpansion(SL)) {
11221 SL =
SM.getSpellingLoc(SL);
11222 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11227 QualType DstTy = DstArg->
getType();
11230 if (!isKnownSizeArray) {
11231 if (PatternType == 1)
11232 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11234 Diag(SL, diag::warn_strncat_src_size) << SR;
11238 if (PatternType == 1)
11239 Diag(SL, diag::warn_strncat_large_size) << SR;
11241 Diag(SL, diag::warn_strncat_src_size) << SR;
11243 SmallString<128> sizeString;
11244 llvm::raw_svector_ostream
OS(sizeString);
11252 Diag(SL, diag::note_strncat_wrong_size)
11257void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11266void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11268 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11269 const Decl *D = Lvalue->getDecl();
11270 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11271 if (!DD->getType()->isReferenceType())
11272 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11276 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11277 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11278 Lvalue->getMemberDecl());
11281void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11283 const auto *Lambda = dyn_cast<LambdaExpr>(
11288 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11289 << CalleeName << 2 ;
11292void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11294 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11295 if (Var ==
nullptr)
11299 << CalleeName << 0 << Var;
11302void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11305 llvm::raw_svector_ostream
OS(SizeString);
11308 if (Kind == clang::CK_BitCast &&
11309 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11311 if (Kind == clang::CK_IntegralToPointer &&
11313 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11316 switch (
Cast->getCastKind()) {
11317 case clang::CK_BitCast:
11318 case clang::CK_IntegralToPointer:
11319 case clang::CK_FunctionToPointerDecay:
11328 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11329 << CalleeName << 0 <<
OS.str();
11333void Sema::CheckFreeArguments(
const CallExpr *E) {
11334 const std::string CalleeName =
11339 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11341 case UnaryOperator::Opcode::UO_AddrOf:
11342 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11343 case UnaryOperator::Opcode::UO_Plus:
11344 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11349 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11351 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11353 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11354 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11355 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11361 << CalleeName << 1 ;
11366 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11367 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11371Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11380 Diag(ReturnLoc, diag::warn_null_ret)
11390 if (Op == OO_New || Op == OO_Array_New) {
11391 const FunctionProtoType *Proto
11395 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11401 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11406 if (
Context.getTargetInfo().getTriple().isPPC64())
11418 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11419 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11420 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11421 return FPLiteral && FPCast;
11424 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11430 llvm::APFloat TargetC = FPLiteral->
getValue();
11431 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11432 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11436 Diag(Loc, diag::warn_float_compare_literal)
11437 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11450 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11451 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11452 if (DRL->getDecl() == DRR->getDecl())
11460 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11461 if (FLL->isExact())
11463 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11464 if (FLR->isExact())
11468 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11469 CL &&
CL->getBuiltinCallee())
11472 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11473 CR && CR->getBuiltinCallee())
11477 Diag(Loc, diag::warn_floatingpoint_eq)
11498 IntRange(
unsigned Width,
bool NonNegative)
11499 : Width(Width), NonNegative(NonNegative) {}
11502 unsigned valueBits()
const {
11503 return NonNegative ? Width : Width - 1;
11507 static IntRange forBoolType() {
11508 return IntRange(1,
true);
11512 static IntRange forValueOfType(ASTContext &
C, QualType T) {
11513 return forValueOfCanonicalType(
C,
11518 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *T) {
11521 if (
const auto *VT = dyn_cast<VectorType>(T))
11522 T = VT->getElementType().getTypePtr();
11523 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11524 T = MT->getElementType().getTypePtr();
11525 if (
const auto *CT = dyn_cast<ComplexType>(T))
11526 T = CT->getElementType().getTypePtr();
11527 if (
const auto *AT = dyn_cast<AtomicType>(T))
11528 T = AT->getValueType().getTypePtr();
11529 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11530 T = OBT->getUnderlyingType().getTypePtr();
11532 if (!
C.getLangOpts().CPlusPlus) {
11535 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11540 if (
Enum->isFixed()) {
11541 return IntRange(
C.getIntWidth(QualType(T, 0)),
11542 !
Enum->getIntegerType()->isSignedIntegerType());
11545 unsigned NumPositive =
Enum->getNumPositiveBits();
11546 unsigned NumNegative =
Enum->getNumNegativeBits();
11548 if (NumNegative == 0)
11549 return IntRange(NumPositive,
true);
11551 return IntRange(std::max(NumPositive + 1, NumNegative),
11555 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11556 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11569 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *T) {
11572 if (
const VectorType *VT = dyn_cast<VectorType>(T))
11573 T = VT->getElementType().getTypePtr();
11574 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11575 T = MT->getElementType().getTypePtr();
11576 if (
const ComplexType *CT = dyn_cast<ComplexType>(T))
11577 T = CT->getElementType().getTypePtr();
11578 if (
const AtomicType *AT = dyn_cast<AtomicType>(T))
11579 T = AT->getValueType().getTypePtr();
11581 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11582 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11583 T = OBT->getUnderlyingType().getTypePtr();
11585 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11586 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11595 static IntRange join(IntRange L, IntRange R) {
11596 bool Unsigned = L.NonNegative &&
R.NonNegative;
11597 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11598 L.NonNegative &&
R.NonNegative);
11602 static IntRange bit_and(IntRange L, IntRange R) {
11603 unsigned Bits = std::max(L.Width,
R.Width);
11604 bool NonNegative =
false;
11605 if (L.NonNegative) {
11606 Bits = std::min(Bits, L.Width);
11607 NonNegative =
true;
11609 if (
R.NonNegative) {
11610 Bits = std::min(Bits,
R.Width);
11611 NonNegative =
true;
11613 return IntRange(Bits, NonNegative);
11617 static IntRange sum(IntRange L, IntRange R) {
11618 bool Unsigned = L.NonNegative &&
R.NonNegative;
11619 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11624 static IntRange difference(IntRange L, IntRange R) {
11628 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11629 bool Unsigned = L.NonNegative &&
R.Width == 0;
11630 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11636 static IntRange product(IntRange L, IntRange R) {
11640 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11641 bool Unsigned = L.NonNegative &&
R.NonNegative;
11642 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11647 static IntRange rem(IntRange L, IntRange R) {
11651 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11659 if (value.isSigned() && value.isNegative())
11660 return IntRange(value.getSignificantBits(),
false);
11662 if (value.getBitWidth() > MaxWidth)
11663 value = value.trunc(MaxWidth);
11667 return IntRange(value.getActiveBits(),
true);
11671 if (result.
isInt())
11678 R = IntRange::join(R, El);
11686 return IntRange::join(R, I);
11701 Ty = AtomicRHS->getValueType();
11720 bool InConstantContext,
11721 bool Approximate) {
11732 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11733 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11737 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11739 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11740 CE->getCastKind() == CK_BooleanToSignedIntegral;
11743 if (!isIntegerCast)
11744 return OutputTypeRange;
11747 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11748 InConstantContext, Approximate);
11750 return std::nullopt;
11753 if (SubRange->Width >= OutputTypeRange.Width)
11754 return OutputTypeRange;
11758 return IntRange(SubRange->Width,
11759 SubRange->NonNegative || OutputTypeRange.NonNegative);
11762 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11765 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11767 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11768 InConstantContext, Approximate);
11773 Expr *TrueExpr = CO->getTrueExpr();
11775 return std::nullopt;
11777 std::optional<IntRange> L =
11780 return std::nullopt;
11782 Expr *FalseExpr = CO->getFalseExpr();
11784 return std::nullopt;
11786 std::optional<IntRange> R =
11789 return std::nullopt;
11791 return IntRange::join(*L, *R);
11794 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11795 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11797 switch (BO->getOpcode()) {
11799 llvm_unreachable(
"builtin <=> should have class type");
11810 return IntRange::forBoolType();
11839 Combine = IntRange::bit_and;
11847 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11848 if (I->getValue() == 1) {
11849 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11850 return IntRange(R.Width,
true);
11860 case BO_ShrAssign: {
11862 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11864 return std::nullopt;
11868 if (std::optional<llvm::APSInt> shift =
11869 BO->getRHS()->getIntegerConstantExpr(
C)) {
11870 if (shift->isNonNegative()) {
11871 if (shift->uge(L->Width))
11872 L->Width = (L->NonNegative ? 0 : 1);
11874 L->Width -= shift->getZExtValue();
11888 Combine = IntRange::sum;
11892 if (BO->getLHS()->getType()->isPointerType())
11895 Combine = IntRange::difference;
11900 Combine = IntRange::product;
11909 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11911 return std::nullopt;
11914 if (std::optional<llvm::APSInt> divisor =
11915 BO->getRHS()->getIntegerConstantExpr(
C)) {
11916 unsigned log2 = divisor->logBase2();
11917 if (
log2 >= L->Width)
11918 L->Width = (L->NonNegative ? 0 : 1);
11920 L->Width = std::min(L->Width -
log2, MaxWidth);
11928 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11930 return std::nullopt;
11932 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11936 Combine = IntRange::rem;
11948 unsigned opWidth =
C.getIntWidth(T);
11950 InConstantContext, Approximate);
11952 return std::nullopt;
11955 InConstantContext, Approximate);
11957 return std::nullopt;
11959 IntRange
C = Combine(*L, *R);
11960 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
11961 C.Width = std::min(
C.Width, MaxWidth);
11965 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11966 switch (UO->getOpcode()) {
11969 return IntRange::forBoolType();
11983 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11986 return std::nullopt;
11991 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12001 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12004 return std::nullopt;
12009 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12019 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
12020 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
12024 return IntRange(BitField->getBitWidthValue(),
12025 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12028 return std::nullopt;
12034 bool InConstantContext,
12035 bool Approximate) {
12044 const llvm::fltSemantics &Src,
12045 const llvm::fltSemantics &Tgt) {
12046 llvm::APFloat truncated = value;
12049 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12050 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12052 return truncated.bitwiseIsEqual(value);
12061 const llvm::fltSemantics &Src,
12062 const llvm::fltSemantics &Tgt) {
12086 bool IsListInit =
false);
12101 return MacroName !=
"YES" && MacroName !=
"NO" &&
12102 MacroName !=
"true" && MacroName !=
"false";
12110 (!E->
getType()->isSignedIntegerType() ||
12125struct PromotedRange {
12127 llvm::APSInt PromotedMin;
12129 llvm::APSInt PromotedMax;
12131 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12133 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12134 else if (
R.Width >= BitWidth && !
Unsigned) {
12138 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12139 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12141 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12142 .extOrTrunc(BitWidth);
12143 PromotedMin.setIsUnsigned(
Unsigned);
12145 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12146 .extOrTrunc(BitWidth);
12147 PromotedMax.setIsUnsigned(
Unsigned);
12152 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12162 InRangeFlag = 0x40,
12165 Min =
LE | InRangeFlag,
12166 InRange = InRangeFlag,
12167 Max =
GE | InRangeFlag,
12170 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12175 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12176 Value.isUnsigned() == PromotedMin.isUnsigned());
12177 if (!isContiguous()) {
12178 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12179 if (
Value.isMinValue())
return Min;
12180 if (
Value.isMaxValue())
return Max;
12181 if (
Value >= PromotedMin)
return InRange;
12182 if (
Value <= PromotedMax)
return InRange;
12186 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12187 case -1:
return Less;
12188 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12190 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12191 case -1:
return InRange;
12192 case 0:
return Max;
12197 llvm_unreachable(
"impossible compare result");
12200 static std::optional<StringRef>
12202 if (Op == BO_Cmp) {
12204 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12206 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12207 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12208 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12209 return std::nullopt;
12216 }
else if (Op == BO_NE) {
12220 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12227 if (Op == BO_GE || Op == BO_LE)
12228 std::swap(TrueFlag, FalseFlag);
12231 return StringRef(
"true");
12233 return StringRef(
"false");
12234 return std::nullopt;
12241 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12242 if (ICE->getCastKind() != CK_IntegralCast &&
12243 ICE->getCastKind() != CK_NoOp)
12245 E = ICE->getSubExpr();
12254 enum ConstantValueKind {
12259 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12260 return BL->getValue() ? ConstantValueKind::LiteralTrue
12261 : ConstantValueKind::LiteralFalse;
12262 return ConstantValueKind::Miscellaneous;
12267 const llvm::APSInt &
Value,
12268 bool RhsConstant) {
12284 if (
Constant->getType()->isEnumeralType() &&
12290 if (!OtherValueRange)
12295 OtherT = AT->getValueType();
12296 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12300 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12306 bool OtherIsBooleanDespiteType =
12308 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12309 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12313 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12314 Value.isUnsigned());
12315 auto Cmp = OtherPromotedValueRange.compare(
Value);
12322 bool TautologicalTypeCompare =
false;
12324 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12325 Value.isUnsigned());
12326 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12329 TautologicalTypeCompare =
true;
12337 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12346 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12352 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12353 Other->getType()->isUnsignedIntegerOrEnumerationType())
12354 TautologicalTypeCompare =
true;
12359 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12360 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12364 llvm::raw_svector_ostream OS(PrettySourceValue);
12366 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12367 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12368 Constant->IgnoreParenImpCasts())) {
12369 OS << (BL->getValue() ?
"YES" :
"NO");
12374 if (!TautologicalTypeCompare) {
12376 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12382 if (IsObjCSignedCharBool) {
12384 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12385 << OS.str() << *
Result);
12392 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12396 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12397 : diag::warn_tautological_bool_compare)
12399 << OtherIsBooleanDespiteType << *
Result
12406 ? diag::warn_unsigned_enum_always_true_comparison
12407 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12408 : diag::warn_unsigned_always_true_comparison)
12409 : diag::warn_tautological_constant_compare;
12445 if (T->isIntegralType(S.
Context)) {
12446 std::optional<llvm::APSInt> RHSValue =
12448 std::optional<llvm::APSInt> LHSValue =
12452 if (RHSValue && LHSValue)
12456 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12458 const bool RhsConstant = (
bool)RHSValue;
12459 Expr *Const = RhsConstant ? RHS : LHS;
12461 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12470 if (!T->hasUnsignedIntegerRepresentation()) {
12484 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12486 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12492 Expr *signedOperand, *unsignedOperand;
12495 "unsigned comparison between two signed integer expressions?");
12496 signedOperand = LHS;
12497 unsignedOperand = RHS;
12499 signedOperand = RHS;
12500 unsignedOperand = LHS;
12506 std::optional<IntRange> signedRange =
12518 if (signedRange->NonNegative)
12530 if (!unsignedRange)
12535 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12537 if (unsignedRange->Width < comparisonWidth)
12542 S.
PDiag(diag::warn_mixed_sign_comparison)
12561 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12566 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12567 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12568 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12569 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12570 << BitfieldEnumDecl;
12577 Init->isValueDependent() ||
12578 Init->isTypeDependent())
12581 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12591 const PreferredTypeAttr *PTAttr =
nullptr;
12593 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12595 ED = PTAttr->getType()->getAsEnumDecl();
12603 bool SignedEnum = ED->getNumNegativeBits() > 0;
12610 unsigned DiagID = 0;
12611 if (SignedEnum && !SignedBitfield) {
12614 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12616 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12617 }
else if (SignedBitfield && !SignedEnum &&
12618 ED->getNumPositiveBits() == FieldWidth) {
12621 ? diag::warn_signed_bitfield_enum_conversion
12622 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12625 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12630 << SignedEnum << TypeRange;
12632 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12639 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12640 ED->getNumNegativeBits())
12641 : ED->getNumPositiveBits();
12644 if (BitsNeeded > FieldWidth) {
12648 ? diag::warn_bitfield_too_small_for_enum
12649 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12650 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12654 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12664 unsigned OriginalWidth =
Value.getBitWidth();
12670 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12671 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12678 if (!
Value.isSigned() ||
Value.isNegative())
12679 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12680 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12681 OriginalWidth =
Value.getSignificantBits();
12683 if (OriginalWidth <= FieldWidth)
12687 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12691 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12692 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12696 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12698 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12699 ? diag::warn_impcast_single_bit_bitield_precision_constant
12700 : diag::warn_impcast_bitfield_precision_constant)
12701 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12702 <<
Init->getSourceRange();
12739 bool PruneControlFlow =
false) {
12746 if (T.hasAddressSpace())
12748 if (PruneControlFlow) {
12762 bool PruneControlFlow =
false) {
12769 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
12774 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12775 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12780 llvm::APFloat
Value(0.0);
12786 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12791 diag::warn_impcast_float_integer, PruneWarnings);
12794 bool isExact =
false;
12797 T->hasUnsignedIntegerRepresentation());
12798 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
12799 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12807 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12808 precision = (precision * 59 + 195) / 196;
12809 Value.toString(PrettySourceValue, precision);
12813 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12814 << PrettySourceValue);
12817 if (
Result == llvm::APFloat::opOK && isExact) {
12818 if (IsLiteral)
return;
12819 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
12825 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
12828 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12829 : diag::warn_impcast_float_to_integer_out_of_range,
12832 unsigned DiagID = 0;
12835 DiagID = diag::warn_impcast_literal_float_to_integer;
12836 }
else if (IntegerValue == 0) {
12837 if (
Value.isZero()) {
12839 diag::warn_impcast_float_integer, PruneWarnings);
12842 DiagID = diag::warn_impcast_float_to_integer_zero;
12844 if (IntegerValue.isUnsigned()) {
12845 if (!IntegerValue.isMaxValue()) {
12847 diag::warn_impcast_float_integer, PruneWarnings);
12850 if (!IntegerValue.isMaxSignedValue() &&
12851 !IntegerValue.isMinSignedValue()) {
12853 diag::warn_impcast_float_integer, PruneWarnings);
12857 DiagID = diag::warn_impcast_float_to_integer;
12862 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12864 IntegerValue.toString(PrettyTargetValue);
12866 if (PruneWarnings) {
12870 << PrettySourceValue << PrettyTargetValue
12883 "Must be compound assignment operation");
12894 ->getComputationResultType()
12901 if (ResultBT->isInteger())
12903 E->
getExprLoc(), diag::warn_impcast_float_integer);
12905 if (!ResultBT->isFloatingPoint())
12914 diag::warn_impcast_float_result_precision);
12919 if (!Range.Width)
return "0";
12921 llvm::APSInt ValueInRange =
Value;
12922 ValueInRange.setIsSigned(!Range.NonNegative);
12923 ValueInRange = ValueInRange.trunc(Range.Width);
12924 return toString(ValueInRange, 10);
12934 const Type *Source =
12936 if (
Target->isDependentType())
12939 const auto *FloatCandidateBT =
12940 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12941 const Type *BoolCandidateType = ToBool ?
Target : Source;
12944 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12949 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12955 S, TheCall->
getArg(I - 1),
false));
12957 S, TheCall->
getArg(I + 1),
false));
12962 diag::warn_impcast_floating_point_to_bool);
12977 if (!IsGNUNullExpr && !HasNullPtrType)
12981 if (T->isAnyPointerType() || T->isBlockPointerType() ||
12982 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
12985 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12998 if (IsGNUNullExpr && Loc.
isMacroID()) {
13001 if (MacroName ==
"NULL")
13009 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13023 const char FirstLiteralCharacter =
13025 if (FirstLiteralCharacter ==
'0')
13031 if (CC.
isValid() && T->isCharType()) {
13032 const char FirstContextCharacter =
13034 if (FirstContextCharacter ==
'{')
13042 const auto *IL = dyn_cast<IntegerLiteral>(E);
13044 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13045 if (UO->getOpcode() == UO_Minus)
13046 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13057 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13061 if (Opc == BO_Shl) {
13064 if (LHS && LHS->getValue() == 0)
13065 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13067 RHS->getValue().isNonNegative() &&
13069 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13070 << (
Result.Val.getInt() != 0);
13072 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13079 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13084 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13085 (RHS->getValue() == 0 || RHS->getValue() == 1))
13088 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13089 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13097 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13103 if (Source->isChar16Type() &&
Target->isChar32Type())
13109 llvm::APSInt
Value(32);
13111 bool IsASCII =
Value <= 0x7F;
13112 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13113 bool ConversionPreservesSemantics =
13114 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13116 if (!ConversionPreservesSemantics) {
13117 auto IsSingleCodeUnitCP = [](
const QualType &T,
13118 const llvm::APSInt &
Value) {
13119 if (T->isChar8Type())
13120 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13121 if (T->isChar16Type())
13122 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13123 assert(T->isChar32Type());
13124 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13127 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13136 LosesPrecision ? diag::warn_impcast_unicode_precision
13137 : diag::warn_impcast_unicode_char_type);
13142 From =
Context.getCanonicalType(From);
13143 To =
Context.getCanonicalType(To);
13146 From = MaybePointee;
13153 if (FromFn->getCFIUncheckedCalleeAttr() &&
13154 !ToFn->getCFIUncheckedCalleeAttr())
13162 bool *ICContext,
bool IsListInit) {
13167 if (Source ==
Target)
return;
13168 if (
Target->isDependentType())
return;
13178 if (Source->isAtomicType())
13182 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13188 diag::warn_impcast_string_literal_to_bool);
13194 diag::warn_impcast_objective_c_literal_to_bool);
13196 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13208 if (
ObjC().isSignedCharBool(T) && Source->isIntegralType(
Context)) {
13211 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13213 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13222 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13224 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13235 diag::err_impcast_incompatible_type);
13240 ? diag::err_impcast_complex_scalar
13241 : diag::warn_impcast_complex_scalar);
13250 if (
Target->isSveVLSBuiltinType() &&
13257 if (
Target->isRVVVLSBuiltinType() &&
13267 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_vector_scalar);
13275 diag::warn_hlsl_impcast_vector_truncation);
13287 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13288 Target = VecTy->getElementType().getTypePtr();
13292 if (
Target->isScalarType())
13293 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_matrix_scalar);
13301 diag::warn_hlsl_impcast_matrix_truncation);
13307 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13308 Target = MatTy->getElementType().getTypePtr();
13310 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13316 const Type *OriginalTarget =
Context.getCanonicalType(T).getTypePtr();
13319 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13321 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13360 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_float_precision);
13363 else if (Order < 0) {
13367 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_double_promotion);
13373 if (TargetBT && TargetBT->
isInteger()) {
13400 diag::warn_impcast_floating_point_to_bool);
13408 if (Source->isFixedPointType()) {
13409 if (
Target->isUnsaturatedFixedPointType()) {
13413 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13414 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(T);
13415 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(T);
13418 PDiag(diag::warn_impcast_fixed_point_range)
13419 <<
Value.toString() << T
13425 }
else if (
Target->isIntegerType()) {
13429 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13432 llvm::APSInt IntResult = FXResult.convertToInt(
13433 Context.getIntWidth(T),
Target->isSignedIntegerOrEnumerationType(),
13438 PDiag(diag::warn_impcast_fixed_point_range)
13439 << FXResult.toString() << T
13446 }
else if (
Target->isUnsaturatedFixedPointType()) {
13447 if (Source->isIntegerType()) {
13454 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13455 Value,
Context.getFixedPointSemantics(T), &Overflowed);
13459 PDiag(diag::warn_impcast_fixed_point_range)
13480 unsigned int SourcePrecision =
SourceRange->Width;
13484 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13487 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13488 SourcePrecision > TargetPrecision) {
13490 if (std::optional<llvm::APSInt> SourceInt =
13495 llvm::APFloat TargetFloatValue(
13497 llvm::APFloat::opStatus ConversionStatus =
13498 TargetFloatValue.convertFromAPInt(
13500 llvm::APFloat::rmNearestTiesToEven);
13502 if (ConversionStatus != llvm::APFloat::opOK) {
13504 SourceInt->toString(PrettySourceValue, 10);
13506 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13510 PDiag(diag::warn_impcast_integer_float_precision_constant)
13511 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13517 diag::warn_impcast_integer_float_precision);
13526 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13531 if (
Target->isBooleanType())
13535 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13539 if (!Source->isIntegerType() || !
Target->isIntegerType())
13544 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13547 if (
ObjC().isSignedCharBool(T) && !Source->isCharType() &&
13550 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13555 if (!LikelySourceRange)
13558 IntRange SourceTypeRange =
13559 IntRange::forTargetOfCanonicalType(
Context, Source);
13560 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13562 if (LikelySourceRange->Width > TargetRange.Width) {
13566 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13567 if (TargetOBT->isWrapKind()) {
13574 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13575 if (SourceOBT->isWrapKind()) {
13585 llvm::APSInt
Value(32);
13595 PDiag(diag::warn_impcast_integer_precision_constant)
13596 << PrettySourceValue << PrettyTargetValue
13606 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13607 if (UO->getOpcode() == UO_Minus)
13609 *
this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
13612 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13613 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_integer_64_32,
13616 diag::warn_impcast_integer_precision);
13619 if (TargetRange.Width > SourceTypeRange.Width) {
13620 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13621 if (UO->getOpcode() == UO_Minus)
13622 if (Source->isUnsignedIntegerType()) {
13623 if (
Target->isUnsignedIntegerType())
13625 diag::warn_impcast_high_order_zero_bits);
13626 if (
Target->isSignedIntegerType())
13628 diag::warn_impcast_nonnegative_result);
13632 if (TargetRange.Width == LikelySourceRange->Width &&
13633 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13634 Source->isSignedIntegerType()) {
13648 PDiag(diag::warn_impcast_integer_precision_constant)
13649 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13659 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13660 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13661 LikelySourceRange->Width == TargetRange.Width))) {
13665 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13667 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13671 unsigned DiagID = diag::warn_impcast_integer_sign;
13679 DiagID = diag::warn_impcast_integer_sign_conditional;
13691 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_int_to_enum);
13696 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13698 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13699 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13700 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13701 TargetEnum->getDecl()->hasNameForLinkage() &&
13702 SourceEnum != TargetEnum) {
13707 diag::warn_impcast_different_enum_types);
13721 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13734 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13735 TrueExpr = BCO->getCommon();
13737 bool Suspicious =
false;
13741 if (T->isBooleanType())
13746 if (!Suspicious)
return;
13749 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13754 if (E->
getType() == T)
return;
13756 Suspicious =
false;
13761 E->
getType(), CC, &Suspicious);
13778struct AnalyzeImplicitConversionsWorkItem {
13787 bool ExtraCheckForImplicitConversion,
13790 WorkList.push_back({E, CC,
false});
13792 if (ExtraCheckForImplicitConversion && E->
getType() != T)
13799 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13801 Expr *OrigE = Item.E;
13820 Expr *SourceExpr = E;
13825 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13826 if (
auto *Src = OVE->getSourceExpr())
13829 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13830 if (UO->getOpcode() == UO_Not &&
13831 UO->getSubExpr()->isKnownToHaveBooleanValue())
13832 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13836 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13837 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13838 BO->getLHS()->isKnownToHaveBooleanValue() &&
13839 BO->getRHS()->isKnownToHaveBooleanValue() &&
13840 BO->getLHS()->HasSideEffects(S.
Context) &&
13841 BO->getRHS()->HasSideEffects(S.
Context)) {
13852 if (SR.str() ==
"&" || SR.str() ==
"|") {
13854 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13855 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13858 BO->getOperatorLoc(),
13859 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13860 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13862 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13880 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13886 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13892 if (SourceExpr->
getType() != T)
13901 for (
auto *SE : POE->semantics())
13902 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13903 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13907 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13908 E = CE->getSubExpr();
13914 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13915 if (InitListE->getNumInits() == 1) {
13916 E = InitListE->getInit(0);
13923 WorkList.push_back({E, CC, IsListInit});
13927 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13928 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13932 if (OutArgE->isInOut())
13933 WorkList.push_back(
13934 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13935 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13941 if (BO->isComparisonOp())
13945 if (BO->getOpcode() == BO_Assign)
13948 if (BO->isAssignmentOp())
13964 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13966 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13970 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13971 if (ChildExpr == CSE->getOperand())
13977 if (IsLogicalAndOperator &&
13982 WorkList.push_back({ChildExpr, CC, IsListInit});
13996 if (
U->getOpcode() == UO_LNot) {
13998 }
else if (
U->getOpcode() != UO_AddrOf) {
13999 if (
U->getSubExpr()->getType()->isAtomicType())
14000 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14001 diag::warn_atomic_implicit_seq_cst);
14012 WorkList.push_back({OrigE, CC, IsListInit});
14013 while (!WorkList.empty())
14025 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14028 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14029 if (!M->getMemberDecl()->getType()->isReferenceType())
14031 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14032 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14034 FD =
Call->getDirectCallee();
14043 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14057 if (
SM.isMacroBodyExpansion(Loc))
14059 Loc =
SM.getImmediateMacroCallerLoc(Loc);
14083 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14084 : diag::warn_this_bool_conversion;
14089 bool IsAddressOf =
false;
14091 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14092 if (UO->getOpcode() != UO_AddrOf)
14094 IsAddressOf =
true;
14095 E = UO->getSubExpr();
14099 unsigned DiagID = IsCompare
14100 ? diag::warn_address_of_reference_null_compare
14101 : diag::warn_address_of_reference_bool_conversion;
14109 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14112 llvm::raw_string_ostream S(Str);
14114 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14115 : diag::warn_cast_nonnull_to_bool;
14118 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14123 if (
auto *Callee =
Call->getDirectCallee()) {
14124 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14125 ComplainAboutNonnullParamOrCall(A);
14134 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14135 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14136 MRecordDecl && MRecordDecl->isLambda()) {
14139 << MRecordDecl->getSourceRange() << Range << IsEqual;
14149 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14150 D = M->getMemberDecl();
14158 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14161 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14162 ComplainAboutNonnullParamOrCall(A);
14166 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14170 auto ParamIter = llvm::find(FD->
parameters(), PV);
14172 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14176 ComplainAboutNonnullParamOrCall(
NonNull);
14181 if (ArgNo.getASTIndex() == ParamNo) {
14182 ComplainAboutNonnullParamOrCall(
NonNull);
14193 const bool IsFunction = T->isFunctionType();
14196 if (IsAddressOf && IsFunction) {
14201 if (!IsAddressOf && !IsFunction && !IsArray)
14206 llvm::raw_string_ostream S(Str);
14209 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14210 : diag::warn_impcast_pointer_to_bool;
14217 DiagType = AddressOf;
14218 else if (IsFunction)
14219 DiagType = FunctionPointer;
14221 DiagType = ArrayPointer;
14223 llvm_unreachable(
"Could not determine diagnostic.");
14225 << Range << IsEqual;
14238 if (ReturnType.
isNull())
14269 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14270 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14272 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14273 Target->isUnsignedIntegerType()) {
14277 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14278 : diag::warn_impcast_overflow_behavior_pedantic;
14282 ? diag::warn_impcast_overflow_behavior_assignment
14283 : diag::warn_impcast_overflow_behavior;
14289 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14290 if (TargetOBT->isWrapKind()) {
14310 CheckArrayAccess(E);
14320void Sema::CheckForIntOverflow (
const Expr *E) {
14322 SmallVector<const Expr *, 2> Exprs(1, E);
14325 const Expr *OriginalE = Exprs.pop_back_val();
14333 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14334 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14337 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14338 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14339 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14341 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14342 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14343 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14344 Exprs.push_back(Temporary->getSubExpr());
14345 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14346 Exprs.push_back(
Array->getIdx());
14347 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14348 Exprs.push_back(Compound->getInitializer());
14349 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14350 New &&
New->isArray()) {
14351 if (
auto ArraySize =
New->getArraySize())
14352 Exprs.push_back(*ArraySize);
14353 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14354 Exprs.push_back(MTE->getSubExpr());
14355 }
while (!Exprs.empty());
14363 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14370 class SequenceTree {
14372 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14373 unsigned Parent : 31;
14374 LLVM_PREFERRED_TYPE(
bool)
14375 unsigned Merged : 1;
14377 SmallVector<Value, 8> Values;
14383 friend class SequenceTree;
14387 explicit Seq(
unsigned N) : Index(N) {}
14390 Seq() : Index(0) {}
14393 SequenceTree() { Values.push_back(
Value(0)); }
14394 Seq root()
const {
return Seq(0); }
14399 Seq allocate(
Seq Parent) {
14400 Values.push_back(
Value(Parent.Index));
14401 return Seq(Values.size() - 1);
14406 Values[S.Index].Merged =
true;
14412 bool isUnsequenced(
Seq Cur,
Seq Old) {
14413 unsigned C = representative(Cur.Index);
14414 unsigned Target = representative(Old.Index);
14418 C = Values[
C].Parent;
14425 unsigned representative(
unsigned K) {
14426 if (Values[K].Merged)
14428 return Values[K].Parent = representative(Values[K].Parent);
14434 using Object =
const NamedDecl *;
14448 UK_ModAsSideEffect,
14450 UK_Count = UK_ModAsSideEffect + 1
14456 const Expr *UsageExpr =
nullptr;
14457 SequenceTree::Seq
Seq;
14463 Usage Uses[UK_Count];
14466 bool Diagnosed =
false;
14470 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14478 UsageInfoMap UsageMap;
14481 SequenceTree::Seq Region;
14485 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14489 SmallVectorImpl<const Expr *> &WorkList;
14496 struct SequencedSubexpression {
14497 SequencedSubexpression(SequenceChecker &
Self)
14498 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14499 Self.ModAsSideEffect = &ModAsSideEffect;
14502 ~SequencedSubexpression() {
14503 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14507 UsageInfo &UI =
Self.UsageMap[M.first];
14508 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14509 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14510 SideEffectUsage = M.second;
14512 Self.ModAsSideEffect = OldModAsSideEffect;
14515 SequenceChecker &
Self;
14516 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14517 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14524 class EvaluationTracker {
14526 EvaluationTracker(SequenceChecker &
Self)
14528 Self.EvalTracker =
this;
14531 ~EvaluationTracker() {
14532 Self.EvalTracker = Prev;
14534 Prev->EvalOK &= EvalOK;
14537 bool evaluate(
const Expr *E,
bool &
Result) {
14542 Self.SemaRef.isConstantEvaluatedContext());
14547 SequenceChecker &
Self;
14548 EvaluationTracker *Prev;
14549 bool EvalOK =
true;
14550 } *EvalTracker =
nullptr;
14554 Object getObject(
const Expr *E,
bool Mod)
const {
14556 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14557 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14558 return getObject(UO->getSubExpr(), Mod);
14559 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14560 if (BO->getOpcode() == BO_Comma)
14561 return getObject(BO->getRHS(), Mod);
14562 if (Mod && BO->isAssignmentOp())
14563 return getObject(BO->getLHS(), Mod);
14564 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14567 return ME->getMemberDecl();
14568 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14577 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14579 Usage &U = UI.Uses[UK];
14580 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14584 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14585 ModAsSideEffect->push_back(std::make_pair(O, U));
14587 U.UsageExpr = UsageExpr;
14597 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14598 UsageKind OtherKind,
bool IsModMod) {
14602 const Usage &U = UI.Uses[OtherKind];
14603 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14606 const Expr *Mod = U.UsageExpr;
14607 const Expr *ModOrUse = UsageExpr;
14608 if (OtherKind == UK_Use)
14609 std::swap(Mod, ModOrUse);
14613 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14614 : diag::warn_unsequenced_mod_use)
14615 << O << SourceRange(ModOrUse->
getExprLoc()));
14616 UI.Diagnosed =
true;
14645 void notePreUse(
Object O,
const Expr *UseExpr) {
14646 UsageInfo &UI = UsageMap[O];
14648 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14651 void notePostUse(
Object O,
const Expr *UseExpr) {
14652 UsageInfo &UI = UsageMap[O];
14653 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14655 addUsage(O, UI, UseExpr, UK_Use);
14658 void notePreMod(
Object O,
const Expr *ModExpr) {
14659 UsageInfo &UI = UsageMap[O];
14661 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14662 checkUsage(O, UI, ModExpr, UK_Use,
false);
14665 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14666 UsageInfo &UI = UsageMap[O];
14667 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14669 addUsage(O, UI, ModExpr, UK);
14673 SequenceChecker(Sema &S,
const Expr *E,
14674 SmallVectorImpl<const Expr *> &WorkList)
14675 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14679 (void)this->WorkList;
14682 void VisitStmt(
const Stmt *S) {
14686 void VisitExpr(
const Expr *E) {
14688 Base::VisitStmt(E);
14691 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14692 for (
auto *Sub : CSE->
children()) {
14693 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14708 void VisitCastExpr(
const CastExpr *E) {
14720 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14721 const Expr *SequencedAfter) {
14722 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14723 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14724 SequenceTree::Seq OldRegion = Region;
14727 SequencedSubexpression SeqBefore(*
this);
14728 Region = BeforeRegion;
14729 Visit(SequencedBefore);
14732 Region = AfterRegion;
14733 Visit(SequencedAfter);
14735 Region = OldRegion;
14737 Tree.merge(BeforeRegion);
14738 Tree.merge(AfterRegion);
14741 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14746 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14753 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14754 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14755 void VisitBinPtrMem(
const BinaryOperator *BO) {
14760 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14767 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14768 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14769 void VisitBinShlShr(
const BinaryOperator *BO) {
14773 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14780 void VisitBinComma(
const BinaryOperator *BO) {
14785 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14788 void VisitBinAssign(
const BinaryOperator *BO) {
14789 SequenceTree::Seq RHSRegion;
14790 SequenceTree::Seq LHSRegion;
14792 RHSRegion = Tree.allocate(Region);
14793 LHSRegion = Tree.allocate(Region);
14795 RHSRegion = Region;
14796 LHSRegion = Region;
14798 SequenceTree::Seq OldRegion = Region;
14814 SequencedSubexpression SeqBefore(*
this);
14815 Region = RHSRegion;
14819 Region = LHSRegion;
14823 notePostUse(O, BO);
14827 Region = LHSRegion;
14831 notePostUse(O, BO);
14833 Region = RHSRegion;
14841 Region = OldRegion;
14845 : UK_ModAsSideEffect);
14847 Tree.merge(RHSRegion);
14848 Tree.merge(LHSRegion);
14852 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14853 VisitBinAssign(CAO);
14856 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14857 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14858 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14861 return VisitExpr(UO);
14869 : UK_ModAsSideEffect);
14872 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14873 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14874 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14877 return VisitExpr(UO);
14881 notePostMod(O, UO, UK_ModAsSideEffect);
14884 void VisitBinLOr(
const BinaryOperator *BO) {
14890 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14891 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14892 SequenceTree::Seq OldRegion = Region;
14894 EvaluationTracker Eval(*
this);
14896 SequencedSubexpression Sequenced(*
this);
14897 Region = LHSRegion;
14904 bool EvalResult =
false;
14905 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14906 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14907 if (ShouldVisitRHS) {
14908 Region = RHSRegion;
14912 Region = OldRegion;
14913 Tree.merge(LHSRegion);
14914 Tree.merge(RHSRegion);
14917 void VisitBinLAnd(
const BinaryOperator *BO) {
14923 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14924 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14925 SequenceTree::Seq OldRegion = Region;
14927 EvaluationTracker Eval(*
this);
14929 SequencedSubexpression Sequenced(*
this);
14930 Region = LHSRegion;
14936 bool EvalResult =
false;
14937 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14938 bool ShouldVisitRHS = !EvalOK || EvalResult;
14939 if (ShouldVisitRHS) {
14940 Region = RHSRegion;
14944 Region = OldRegion;
14945 Tree.merge(LHSRegion);
14946 Tree.merge(RHSRegion);
14949 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14954 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14970 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14971 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14972 SequenceTree::Seq OldRegion = Region;
14974 EvaluationTracker Eval(*
this);
14976 SequencedSubexpression Sequenced(*
this);
14977 Region = ConditionRegion;
14987 bool EvalResult =
false;
14988 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14989 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14990 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14991 if (ShouldVisitTrueExpr) {
14992 Region = TrueRegion;
14995 if (ShouldVisitFalseExpr) {
14996 Region = FalseRegion;
15000 Region = OldRegion;
15001 Tree.merge(ConditionRegion);
15002 Tree.merge(TrueRegion);
15003 Tree.merge(FalseRegion);
15006 void VisitCallExpr(
const CallExpr *CE) {
15018 SequencedSubexpression Sequenced(*
this);
15023 SequenceTree::Seq CalleeRegion;
15024 SequenceTree::Seq OtherRegion;
15025 if (SemaRef.getLangOpts().CPlusPlus17) {
15026 CalleeRegion = Tree.allocate(Region);
15027 OtherRegion = Tree.allocate(Region);
15029 CalleeRegion = Region;
15030 OtherRegion = Region;
15032 SequenceTree::Seq OldRegion = Region;
15035 Region = CalleeRegion;
15037 SequencedSubexpression Sequenced(*this);
15038 Visit(CE->getCallee());
15040 Visit(CE->getCallee());
15044 Region = OtherRegion;
15048 Region = OldRegion;
15050 Tree.merge(CalleeRegion);
15051 Tree.merge(OtherRegion);
15069 return VisitCallExpr(CXXOCE);
15080 case OO_MinusEqual:
15082 case OO_SlashEqual:
15083 case OO_PercentEqual:
15084 case OO_CaretEqual:
15087 case OO_LessLessEqual:
15088 case OO_GreaterGreaterEqual:
15089 SequencingKind = RHSBeforeLHS;
15093 case OO_GreaterGreater:
15099 SequencingKind = LHSBeforeRHS;
15103 SequencingKind = LHSBeforeRest;
15107 SequencingKind = NoSequencing;
15111 if (SequencingKind == NoSequencing)
15112 return VisitCallExpr(CXXOCE);
15115 SequencedSubexpression Sequenced(*
this);
15118 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15119 "Should only get there with C++17 and above!");
15120 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15121 "Should only get there with an overloaded binary operator"
15122 " or an overloaded call operator!");
15124 if (SequencingKind == LHSBeforeRest) {
15125 assert(CXXOCE->getOperator() == OO_Call &&
15126 "We should only have an overloaded call operator here!");
15135 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15136 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15137 SequenceTree::Seq OldRegion = Region;
15139 assert(CXXOCE->getNumArgs() >= 1 &&
15140 "An overloaded call operator must have at least one argument"
15141 " for the postfix-expression!");
15142 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15143 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15144 CXXOCE->getNumArgs() - 1);
15148 Region = PostfixExprRegion;
15149 SequencedSubexpression Sequenced(*this);
15150 Visit(PostfixExpr);
15154 Region = ArgsRegion;
15155 for (const Expr *Arg : Args)
15158 Region = OldRegion;
15159 Tree.merge(PostfixExprRegion);
15160 Tree.merge(ArgsRegion);
15162 assert(CXXOCE->getNumArgs() == 2 &&
15163 "Should only have two arguments here!");
15164 assert((SequencingKind == LHSBeforeRHS ||
15165 SequencingKind == RHSBeforeLHS) &&
15166 "Unexpected sequencing kind!");
15170 const Expr *E1 = CXXOCE->getArg(0);
15171 const Expr *E2 = CXXOCE->getArg(1);
15172 if (SequencingKind == RHSBeforeLHS)
15175 return VisitSequencedExpressions(E1, E2);
15182 SequencedSubexpression Sequenced(*
this);
15185 return VisitExpr(CCE);
15188 SequenceExpressionsInOrder(
15194 return VisitExpr(ILE);
15197 SequenceExpressionsInOrder(ILE->
inits());
15209 SequenceTree::Seq Parent = Region;
15210 for (
const Expr *E : ExpressionList) {
15213 Region = Tree.allocate(Parent);
15214 Elts.push_back(Region);
15220 for (
unsigned I = 0; I < Elts.size(); ++I)
15221 Tree.merge(Elts[I]);
15225SequenceChecker::UsageInfo::UsageInfo() =
default;
15229void Sema::CheckUnsequencedOperations(
const Expr *E) {
15230 SmallVector<const Expr *, 8> WorkList;
15231 WorkList.push_back(E);
15232 while (!WorkList.empty()) {
15233 const Expr *Item = WorkList.pop_back_val();
15234 SequenceChecker(*
this, Item, WorkList);
15239 bool IsConstexpr) {
15242 CheckImplicitConversions(E, CheckLoc);
15244 CheckUnsequencedOperations(E);
15246 CheckForIntOverflow(E);
15259 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15263 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15267 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15281 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15285 bool CheckParameterNames) {
15286 bool HasInvalidParm =
false;
15288 assert(Param &&
"null in a parameter list");
15297 if (!Param->isInvalidDecl() &&
15299 diag::err_typecheck_decl_incomplete_type) ||
15301 diag::err_abstract_type_in_decl,
15303 Param->setInvalidDecl();
15304 HasInvalidParm =
true;
15309 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15313 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15321 QualType PType = Param->getOriginalType();
15329 if (!Param->isInvalidDecl()) {
15330 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15331 if (!ClassDecl->isInvalidDecl() &&
15332 !ClassDecl->hasIrrelevantDestructor() &&
15333 !ClassDecl->isDependentContext() &&
15334 ClassDecl->isParamDestroyedInCallee()) {
15346 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15347 if (!Param->getType().isConstQualified())
15348 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15352 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15357 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15358 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15363 if (!Param->isInvalidDecl() &&
15364 Param->getOriginalType()->isWebAssemblyTableType()) {
15365 Param->setInvalidDecl();
15366 HasInvalidParm =
true;
15367 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15371 return HasInvalidParm;
15374std::optional<std::pair<
15383static std::pair<CharUnits, CharUnits>
15391 if (
Base->isVirtual()) {
15398 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15405 DerivedType =
Base->getType();
15408 return std::make_pair(BaseAlignment, Offset);
15412static std::optional<std::pair<CharUnits, CharUnits>>
15418 return std::nullopt;
15423 return std::nullopt;
15427 CharUnits Offset = EltSize * IdxRes->getExtValue();
15430 return std::make_pair(P->first, P->second + Offset);
15436 return std::make_pair(
15437 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15443std::optional<std::pair<
15451 case Stmt::CStyleCastExprClass:
15452 case Stmt::CXXStaticCastExprClass:
15453 case Stmt::ImplicitCastExprClass: {
15455 const Expr *From = CE->getSubExpr();
15456 switch (CE->getCastKind()) {
15461 case CK_UncheckedDerivedToBase:
15462 case CK_DerivedToBase: {
15472 case Stmt::ArraySubscriptExprClass: {
15477 case Stmt::DeclRefExprClass: {
15481 if (!VD->getType()->isReferenceType()) {
15483 if (VD->hasDependentAlignment())
15492 case Stmt::MemberExprClass: {
15494 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15498 std::optional<std::pair<CharUnits, CharUnits>> P;
15507 return std::make_pair(P->first,
15510 case Stmt::UnaryOperatorClass: {
15520 case Stmt::BinaryOperatorClass: {
15532 return std::nullopt;
15537std::optional<std::pair<
15546 case Stmt::CStyleCastExprClass:
15547 case Stmt::CXXStaticCastExprClass:
15548 case Stmt::ImplicitCastExprClass: {
15550 const Expr *From = CE->getSubExpr();
15551 switch (CE->getCastKind()) {
15556 case CK_ArrayToPointerDecay:
15558 case CK_UncheckedDerivedToBase:
15559 case CK_DerivedToBase: {
15569 case Stmt::CXXThisExprClass: {
15574 case Stmt::UnaryOperatorClass: {
15580 case Stmt::BinaryOperatorClass: {
15589 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15590 std::swap(LHS, RHS);
15600 return std::nullopt;
15605 std::optional<std::pair<CharUnits, CharUnits>> P =
15609 return P->first.alignmentAtOffset(P->second);
15627 if (!DestPtr)
return;
15633 if (DestAlign.
isOne())
return;
15637 if (!SrcPtr)
return;
15648 if (SrcAlign >= DestAlign)
return;
15653 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15657void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15659 bool AllowOnePastEnd,
bool IndexNegated) {
15668 const Type *EffectiveType =
15672 Context.getAsConstantArrayType(BaseExpr->
getType());
15675 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15677 const Type *BaseType =
15679 bool IsUnboundedArray =
15681 Context, StrictFlexArraysLevel,
15684 (!IsUnboundedArray && BaseType->isDependentType()))
15692 if (IndexNegated) {
15693 index.setIsUnsigned(
false);
15697 if (IsUnboundedArray) {
15700 if (
index.isUnsigned() || !
index.isNegative()) {
15702 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15704 if (
index.getBitWidth() < AddrBits)
15706 std::optional<CharUnits> ElemCharUnits =
15707 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15710 if (!ElemCharUnits || ElemCharUnits->isZero())
15712 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15717 if (
index.getActiveBits() <= AddrBits) {
15719 llvm::APInt Product(
index);
15721 Product = Product.umul_ov(ElemBytes, Overflow);
15722 if (!Overflow && Product.getActiveBits() <= AddrBits)
15728 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15729 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15731 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15732 MaxElems = MaxElems.udiv(ElemBytes);
15735 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15736 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15741 PDiag(DiagID) << index << AddrBits
15742 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15743 << ElemBytes << MaxElems
15744 << MaxElems.getZExtValue()
15747 const NamedDecl *ND =
nullptr;
15749 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15751 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15753 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15754 ND = ME->getMemberDecl();
15758 PDiag(diag::note_array_declared_here) << ND);
15763 if (index.isUnsigned() || !index.isNegative()) {
15773 llvm::APInt size = ArrayTy->
getSize();
15775 if (BaseType != EffectiveType) {
15783 if (!ptrarith_typesize)
15784 ptrarith_typesize =
Context.getCharWidth();
15786 if (ptrarith_typesize != array_typesize) {
15788 uint64_t ratio = array_typesize / ptrarith_typesize;
15792 if (ptrarith_typesize * ratio == array_typesize)
15793 size *= llvm::APInt(size.getBitWidth(), ratio);
15797 if (size.getBitWidth() > index.getBitWidth())
15798 index = index.zext(size.getBitWidth());
15799 else if (size.getBitWidth() < index.getBitWidth())
15800 size = size.zext(index.getBitWidth());
15806 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15813 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15815 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15816 SourceLocation IndexLoc =
15818 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15823 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15824 : diag::warn_ptr_arith_exceeds_bounds;
15825 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15826 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15830 << index << ArrayTy->
desugar() << CastMsg
15833 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15835 DiagID = diag::warn_ptr_arith_precedes_bounds;
15836 if (index.isNegative()) index = -index;
15843 const NamedDecl *ND =
nullptr;
15845 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15847 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15849 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15850 ND = ME->getMemberDecl();
15854 PDiag(diag::note_array_declared_here) << ND);
15857void Sema::CheckArrayAccess(
const Expr *
expr) {
15858 int AllowOnePastEnd = 0;
15860 expr =
expr->IgnoreParenImpCasts();
15861 switch (
expr->getStmtClass()) {
15862 case Stmt::ArraySubscriptExprClass: {
15865 AllowOnePastEnd > 0);
15869 case Stmt::MemberExprClass: {
15873 case Stmt::CXXMemberCallExprClass: {
15877 case Stmt::ArraySectionExprClass: {
15883 nullptr, AllowOnePastEnd > 0);
15886 case Stmt::UnaryOperatorClass: {
15902 case Stmt::ConditionalOperatorClass: {
15904 if (
const Expr *lhs = cond->
getLHS())
15905 CheckArrayAccess(lhs);
15906 if (
const Expr *rhs = cond->
getRHS())
15907 CheckArrayAccess(rhs);
15910 case Stmt::CXXOperatorCallExprClass: {
15912 for (
const auto *Arg : OCE->arguments())
15913 CheckArrayAccess(Arg);
15923 Expr *RHS,
bool isProperty) {
15935 S.
Diag(Loc, diag::warn_arc_literal_assign)
15937 << (isProperty ? 0 : 1)
15945 Expr *RHS,
bool isProperty) {
15948 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15949 S.
Diag(Loc, diag::warn_arc_retained_assign)
15951 << (isProperty ? 0 : 1)
15955 RHS =
cast->getSubExpr();
15997 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16026 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16027 Diag(Loc, diag::warn_arc_retained_property_assign)
16031 RHS =
cast->getSubExpr();
16054 bool StmtLineInvalid;
16055 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16057 if (StmtLineInvalid)
16060 bool BodyLineInvalid;
16061 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16063 if (BodyLineInvalid)
16067 if (StmtLine != BodyLine)
16082 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16091 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16095 const Stmt *PossibleBody) {
16101 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16102 StmtLoc = FS->getRParenLoc();
16103 Body = FS->getBody();
16104 DiagID = diag::warn_empty_for_body;
16105 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16106 StmtLoc = WS->getRParenLoc();
16107 Body = WS->getBody();
16108 DiagID = diag::warn_empty_while_body;
16113 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16137 if (!ProbableTypo) {
16138 bool BodyColInvalid;
16139 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16141 if (BodyColInvalid)
16144 bool StmtColInvalid;
16147 if (StmtColInvalid)
16150 if (BodyCol > StmtCol)
16151 ProbableTypo =
true;
16154 if (ProbableTypo) {
16156 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16164 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16176 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16178 RHSExpr = CE->
getArg(0);
16179 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16180 CXXSCE && CXXSCE->isXValue())
16181 RHSExpr = CXXSCE->getSubExpr();
16185 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16186 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16189 if (LHSDeclRef && RHSDeclRef) {
16196 auto D =
Diag(OpLoc, diag::warn_self_move)
16212 const Expr *LHSBase = LHSExpr;
16213 const Expr *RHSBase = RHSExpr;
16214 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16215 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16216 if (!LHSME || !RHSME)
16219 while (LHSME && RHSME) {
16226 LHSME = dyn_cast<MemberExpr>(LHSBase);
16227 RHSME = dyn_cast<MemberExpr>(RHSBase);
16230 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16231 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16232 if (LHSDeclRef && RHSDeclRef) {
16239 Diag(OpLoc, diag::warn_self_move)
16246 Diag(OpLoc, diag::warn_self_move)
16270 bool AreUnionMembers =
false) {
16274 assert(((Field1Parent->isStructureOrClassType() &&
16275 Field2Parent->isStructureOrClassType()) ||
16276 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16277 "Can't evaluate layout compatibility between a struct field and a "
16279 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16280 (AreUnionMembers && Field1Parent->isUnionType())) &&
16281 "AreUnionMembers should be 'true' for union fields (only).");
16295 if (Bits1 != Bits2)
16299 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16300 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16303 if (!AreUnionMembers &&
16315 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16316 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16318 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16319 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16324 return isLayoutCompatible(C, F1, F2);
16335 for (
auto *Field1 : RD1->
fields()) {
16336 auto I = UnmatchedFields.begin();
16337 auto E = UnmatchedFields.end();
16339 for ( ; I != E; ++I) {
16341 bool Result = UnmatchedFields.erase(*I);
16351 return UnmatchedFields.empty();
16377 if (
C.hasSameType(T1, T2))
16386 if (TC1 == Type::Enum)
16388 if (TC1 == Type::Record) {
16407 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16438 const ValueDecl **VD, uint64_t *MagicValue,
16439 bool isConstantEvaluated) {
16447 case Stmt::UnaryOperatorClass: {
16456 case Stmt::DeclRefExprClass: {
16462 case Stmt::IntegerLiteralClass: {
16464 llvm::APInt MagicValueAPInt = IL->
getValue();
16465 if (MagicValueAPInt.getActiveBits() <= 64) {
16466 *MagicValue = MagicValueAPInt.getZExtValue();
16472 case Stmt::BinaryConditionalOperatorClass:
16473 case Stmt::ConditionalOperatorClass: {
16478 isConstantEvaluated)) {
16488 case Stmt::BinaryOperatorClass: {
16491 TypeExpr = BO->
getRHS();
16521 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16524 bool isConstantEvaluated) {
16525 FoundWrongKind =
false;
16530 uint64_t MagicValue;
16532 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16536 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16537 if (I->getArgumentKind() != ArgumentKind) {
16538 FoundWrongKind =
true;
16541 TypeInfo.Type = I->getMatchingCType();
16542 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16543 TypeInfo.MustBeNull = I->getMustBeNull();
16554 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16555 if (I == MagicValues->end())
16564 bool LayoutCompatible,
16566 if (!TypeTagForDatatypeMagicValues)
16567 TypeTagForDatatypeMagicValues.reset(
16568 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16571 (*TypeTagForDatatypeMagicValues)[Magic] =
16587 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16588 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16589 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16590 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16593void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16596 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16597 bool IsPointerAttr = Attr->getIsPointer();
16600 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16601 if (TypeTagIdxAST >= ExprArgs.size()) {
16602 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16603 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16606 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16607 bool FoundWrongKind;
16610 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16612 if (FoundWrongKind)
16614 diag::warn_type_tag_for_datatype_wrong_kind)
16620 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16621 if (ArgumentIdxAST >= ExprArgs.size()) {
16622 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16623 << 1 << Attr->getArgumentIdx().getSourceIndex();
16626 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16627 if (IsPointerAttr) {
16629 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16630 if (ICE->getType()->isVoidPointerType() &&
16631 ICE->getCastKind() == CK_BitCast)
16632 ArgumentExpr = ICE->getSubExpr();
16634 QualType ArgumentType = ArgumentExpr->
getType();
16640 if (TypeInfo.MustBeNull) {
16645 diag::warn_type_safety_null_pointer_required)
16653 QualType RequiredType = TypeInfo.Type;
16655 RequiredType =
Context.getPointerType(RequiredType);
16657 bool mismatch =
false;
16658 if (!TypeInfo.LayoutCompatible) {
16659 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16680 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16681 << ArgumentType << ArgumentKind
16682 << TypeInfo.LayoutCompatible << RequiredType
16700 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16708 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
16714 auto &MisalignedMembersForExpr =
16716 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16717 if (MA != MisalignedMembersForExpr.end() &&
16718 (T->isDependentType() || T->isIntegerType() ||
16719 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
16721 T->getPointeeType()) <= MA->Alignment))))
16722 MisalignedMembersForExpr.erase(MA);
16731 const auto *ME = dyn_cast<MemberExpr>(E);
16743 bool AnyIsPacked =
false;
16745 QualType BaseType = ME->getBase()->getType();
16746 if (BaseType->isDependentType())
16750 auto *RD = BaseType->castAsRecordDecl();
16755 auto *FD = dyn_cast<FieldDecl>(MD);
16761 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16762 ReverseMemberChain.push_back(FD);
16765 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16767 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16774 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16785 if (ExpectedAlignment.
isOne())
16790 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16791 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16795 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16799 if (DRE && !TopME->
isArrow()) {
16802 CompleteObjectAlignment =
16803 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16807 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16810 CompleteObjectAlignment < ExpectedAlignment) {
16821 for (
FieldDecl *FDI : ReverseMemberChain) {
16822 if (FDI->hasAttr<PackedAttr>() ||
16823 FDI->getParent()->hasAttr<PackedAttr>()) {
16825 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16831 assert(FD &&
"We did not find a packed FieldDecl!");
16832 Action(E, FD->
getParent(), FD, Alignment);
16836void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16837 using namespace std::placeholders;
16840 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16864bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16865 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16892 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16909 assert(!Args.empty() &&
"Should have at least one argument.");
16911 Expr *Arg0 = Args.front();
16914 auto EmitError = [&](
Expr *ArgI) {
16916 diag::err_typecheck_call_different_arg_types)
16917 << Arg0->
getType() << ArgI->getType();
16922 for (
Expr *ArgI : Args.drop_front())
16933 for (
Expr *ArgI : Args.drop_front()) {
16934 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16937 VecI->getElementType()) ||
16938 Vec0->getNumElements() != VecI->getNumElements()) {
16947std::optional<QualType>
16951 return std::nullopt;
16955 return std::nullopt;
16958 for (
int I = 0; I < 2; ++I) {
16962 return std::nullopt;
16963 Args[I] = Converted.
get();
16970 return std::nullopt;
16973 return std::nullopt;
16975 TheCall->
setArg(0, Args[0]);
16976 TheCall->
setArg(1, Args[1]);
16987 TheCall->
getArg(1), Loc) ||
16989 TheCall->
getArg(2), Loc))
16993 for (
int I = 0; I < 3; ++I) {
16998 Args[I] = Converted.
get();
17001 int ArgOrdinal = 1;
17002 for (
Expr *Arg : Args) {
17004 ArgTyRestr, ArgOrdinal++))
17011 for (
int I = 0; I < 3; ++I)
17012 TheCall->
setArg(I, Args[I]);
17018bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17030bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17039 diag::err_builtin_invalid_arg_type)
17040 << 1 << 2 << 1 << 1 << TyArg;
17054 Expr *Matrix = MatrixArg.
get();
17056 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17059 << 1 << 3 << 0 << 0
17066 QualType ResultType =
Context.getConstantMatrixType(
17067 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17070 TheCall->
setType(ResultType);
17073 TheCall->
setArg(0, Matrix);
17078static std::optional<unsigned>
17086 uint64_t
Dim =
Value->getZExtValue();
17102 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17104 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17112 unsigned PtrArgIdx = 0;
17113 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17114 Expr *RowsExpr = TheCall->
getArg(1);
17115 Expr *ColumnsExpr = TheCall->
getArg(2);
17116 Expr *StrideExpr = TheCall->
getArg(3);
17118 bool ArgError =
false;
17125 PtrExpr = PtrConv.
get();
17126 TheCall->
setArg(0, PtrExpr);
17133 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17134 QualType ElementTy;
17137 << PtrArgIdx + 1 << 0 << 5 << 0
17141 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17145 << PtrArgIdx + 1 << 0 << 5
17152 auto ApplyArgumentConversions = [
this](Expr *E) {
17161 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17163 RowsExpr = RowsConv.
get();
17164 TheCall->
setArg(1, RowsExpr);
17166 RowsExpr =
nullptr;
17168 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17170 ColumnsExpr = ColumnsConv.
get();
17171 TheCall->
setArg(2, ColumnsExpr);
17173 ColumnsExpr =
nullptr;
17184 std::optional<unsigned> MaybeRows;
17188 std::optional<unsigned> MaybeColumns;
17193 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17196 StrideExpr = StrideConv.
get();
17197 TheCall->
setArg(3, StrideExpr);
17200 if (std::optional<llvm::APSInt>
Value =
17203 if (Stride < *MaybeRows) {
17205 diag::err_builtin_matrix_stride_too_small);
17211 if (ArgError || !MaybeRows || !MaybeColumns)
17215 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17226 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17228 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17236 unsigned PtrArgIdx = 1;
17237 Expr *MatrixExpr = TheCall->
getArg(0);
17238 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17239 Expr *StrideExpr = TheCall->
getArg(2);
17241 bool ArgError =
false;
17247 MatrixExpr = MatrixConv.
get();
17248 TheCall->
setArg(0, MatrixExpr);
17255 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17258 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17266 PtrExpr = PtrConv.
get();
17267 TheCall->
setArg(1, PtrExpr);
17275 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17278 << PtrArgIdx + 1 << 0 << 5 << 0
17282 QualType ElementTy = PtrTy->getPointeeType();
17284 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17289 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17291 diag::err_builtin_matrix_pointer_arg_mismatch)
17292 << ElementTy << MatrixTy->getElementType();
17307 StrideExpr = StrideConv.
get();
17308 TheCall->
setArg(2, StrideExpr);
17313 if (std::optional<llvm::APSInt>
Value =
17316 if (Stride < MatrixTy->getNumRows()) {
17318 diag::err_builtin_matrix_stride_too_small);
17338 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17343 llvm::StringSet<> CalleeTCBs;
17344 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17345 CalleeTCBs.insert(A->getTCBName());
17346 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17347 CalleeTCBs.insert(A->getTCBName());
17351 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17352 StringRef CallerTCB = A->getTCBName();
17353 if (CalleeTCBs.count(CallerTCB) == 0) {
17354 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17355 << 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.
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
llvm::MachO::Record Record
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
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 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 BuiltinRotateGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_stdc_rotate_{left,right} was called with two arguments, that the first argument...
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
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 isValidMathElementType(QualType T)
static void DiagnoseDeprecatedHIPAtomic(Sema &S, SourceRange ExprRange, MultiExprArg Args, AtomicExpr::AtomicOp Op)
Deprecate __hip_atomic_* builtins in favour of __scoped_atomic_* equivalents.
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)
#define HIP_ATOMIC_FIXABLE(hip, scoped)
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 QualType getVectorElementType(ASTContext &Context, QualType VecTy)
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 bool BuiltinBitreverseg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bitreverseg was called with a single argument, which is an integer.
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 bool CheckMissingFormatAttribute(Sema *S, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, StringLiteral *ReferenceFormatString, unsigned FormatIdx, unsigned FirstDataArg, FormatStringType FormatType, unsigned CallerParamIdx, SourceLocation Loc)
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 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, std::optional< unsigned > *CallerFormatParamIdx=nullptr, bool IgnoreStringsWithoutSpecifiers=false)
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 ExprResult PointerAuthAuthLoadRelativeAndSign(Sema &S, CallExpr *Call)
static bool BuiltinStdCBuiltin(Sema &S, CallExpr *TheCall, QualType ReturnType)
Checks the __builtin_stdc_* builtins that take a single unsigned integer argument and return either i...
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 for SYCL constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
C Language Family Type Representation.
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
Sema::SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when the only matching conversion function is explicit.
Sema::SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when the expression has incomplete class type.
Sema::SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for one of the candidate conversions.
Sema::SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when there are multiple possible conversion functions.
Sema::SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic complaining that the expression does not have integral or enumeration type.
RotateIntegerConverter(unsigned ArgIndex, bool OnlyUnsigned)
Sema::SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when we picked a conversion function (for cases when we are not allowed to pick a ...
Sema::SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for the explicit conversion function.
bool match(QualType T) override
Determine whether the specified type is a valid destination type for this conversion.
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],...
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APValue & getMatrixElt(unsigned Idx)
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
unsigned getMatrixNumElements() const
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 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++ conversion function within a class.
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 byte-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)
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
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
SourceLocation getEndLoc() const LLVM_READONLY
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,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ 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.
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 * IgnoreCasts() LLVM_READONLY
Skip past any casts which might surround this expression until reaching a fixed point.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
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 ...
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
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.
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() const
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.
UnresolvedSetImpl::iterator iterator
Represents a matrix type, as defined in the Matrix Types clang extensions.
static bool isValidElementType(QualType T, const LangOptions &LangOpts)
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.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
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 hasFlexibleArrayMember() const
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)
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
ContextualImplicitConverter(bool Suppress=false, bool SuppressConversion=false)
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.
bool CheckOverflowBehaviorTypeConversion(Expr *E, QualType T, SourceLocation CC)
Check for overflow behavior type related implicit conversion diagnostics.
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 PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
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...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
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)
bool InOverflowBehaviorAssignmentContext
Track if we're currently analyzing overflow behavior types in assignment context.
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 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,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isMatrixType() 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
bool isSizelessVectorType() const
Returns true for all scalable vector types.
NullabilityKindOrNone getNullability() const
Determine the nullability of the given type.
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
bool isFunctionOrMethodVariadic(const Decl *D)
@ 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)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
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 Indentation
The number of spaces to use to indent each line.
unsigned AnonymousTagNameStyle
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.