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___get_unsafe_stack_start:
2924 case Builtin::BI__builtin___get_unsafe_stack_bottom:
2926 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
2927 <<
"__safestack_get_unsafe_stack_bottom";
2929 case Builtin::BI__builtin___get_unsafe_stack_top:
2931 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
2932 <<
"__safestack_get_unsafe_stack_top";
2934 case Builtin::BI__builtin___get_unsafe_stack_ptr:
2936 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
2937 <<
"__safestack_get_unsafe_stack_ptr";
2939 case Builtin::BI__builtin_cpu_supports:
2940 case Builtin::BI__builtin_cpu_is:
2942 Context.getAuxTargetInfo(), BuiltinID))
2945 case Builtin::BI__builtin_cpu_init:
2946 if (!
Context.getTargetInfo().supportsCpuInit()) {
2952 case Builtin::BI__builtin___CFStringMakeConstantString:
2956 *
this, BuiltinID, TheCall,
2957 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2960 "Wrong # arguments to builtin CFStringMakeConstantString");
2961 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2964 case Builtin::BI__builtin_ms_va_start:
2965 case Builtin::BI__builtin_stdarg_start:
2966 case Builtin::BI__builtin_va_start:
2967 case Builtin::BI__builtin_c23_va_start:
2968 if (BuiltinVAStart(BuiltinID, TheCall))
2971 case Builtin::BI__va_start: {
2972 switch (
Context.getTargetInfo().getTriple().getArch()) {
2973 case llvm::Triple::aarch64:
2974 case llvm::Triple::arm:
2975 case llvm::Triple::thumb:
2976 if (BuiltinVAStartARMMicrosoft(TheCall))
2980 if (BuiltinVAStart(BuiltinID, TheCall))
2988 case Builtin::BI_interlockedbittestandset_acq:
2989 case Builtin::BI_interlockedbittestandset_rel:
2990 case Builtin::BI_interlockedbittestandset_nf:
2991 case Builtin::BI_interlockedbittestandreset_acq:
2992 case Builtin::BI_interlockedbittestandreset_rel:
2993 case Builtin::BI_interlockedbittestandreset_nf:
2996 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3001 case Builtin::BI_bittest64:
3002 case Builtin::BI_bittestandcomplement64:
3003 case Builtin::BI_bittestandreset64:
3004 case Builtin::BI_bittestandset64:
3005 case Builtin::BI_interlockedbittestandreset64:
3006 case Builtin::BI_interlockedbittestandset64:
3009 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3010 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
3015 case Builtin::BI_interlockedbittestandreset64_acq:
3016 case Builtin::BI_interlockedbittestandreset64_rel:
3017 case Builtin::BI_interlockedbittestandreset64_nf:
3018 case Builtin::BI_interlockedbittestandset64_acq:
3019 case Builtin::BI_interlockedbittestandset64_rel:
3020 case Builtin::BI_interlockedbittestandset64_nf:
3025 case Builtin::BI__builtin_set_flt_rounds:
3028 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3029 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
3030 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3031 llvm::Triple::ppc64le}))
3035 case Builtin::BI__builtin_isgreater:
3036 case Builtin::BI__builtin_isgreaterequal:
3037 case Builtin::BI__builtin_isless:
3038 case Builtin::BI__builtin_islessequal:
3039 case Builtin::BI__builtin_islessgreater:
3040 case Builtin::BI__builtin_isunordered:
3041 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3044 case Builtin::BI__builtin_fpclassify:
3045 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3048 case Builtin::BI__builtin_isfpclass:
3049 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3052 case Builtin::BI__builtin_isfinite:
3053 case Builtin::BI__builtin_isinf:
3054 case Builtin::BI__builtin_isinf_sign:
3055 case Builtin::BI__builtin_isnan:
3056 case Builtin::BI__builtin_issignaling:
3057 case Builtin::BI__builtin_isnormal:
3058 case Builtin::BI__builtin_issubnormal:
3059 case Builtin::BI__builtin_iszero:
3060 case Builtin::BI__builtin_signbit:
3061 case Builtin::BI__builtin_signbitf:
3062 case Builtin::BI__builtin_signbitl:
3063 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3066 case Builtin::BI__builtin_shufflevector:
3070 case Builtin::BI__builtin_masked_load:
3071 case Builtin::BI__builtin_masked_expand_load:
3073 case Builtin::BI__builtin_masked_store:
3074 case Builtin::BI__builtin_masked_compress_store:
3076 case Builtin::BI__builtin_masked_gather:
3078 case Builtin::BI__builtin_masked_scatter:
3080 case Builtin::BI__builtin_invoke:
3082 case Builtin::BI__builtin_prefetch:
3083 if (BuiltinPrefetch(TheCall))
3086 case Builtin::BI__builtin_alloca_with_align:
3087 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3088 if (BuiltinAllocaWithAlign(TheCall))
3091 case Builtin::BI__builtin_alloca:
3092 case Builtin::BI__builtin_alloca_uninitialized:
3099 case Builtin::BI__builtin_infer_alloc_token:
3103 case Builtin::BI__arithmetic_fence:
3104 if (BuiltinArithmeticFence(TheCall))
3107 case Builtin::BI__assume:
3108 case Builtin::BI__builtin_assume:
3109 if (BuiltinAssume(TheCall))
3112 case Builtin::BI__builtin_assume_aligned:
3113 if (BuiltinAssumeAligned(TheCall))
3116 case Builtin::BI__builtin_dynamic_object_size:
3117 case Builtin::BI__builtin_object_size:
3121 case Builtin::BI__builtin_longjmp:
3122 if (BuiltinLongjmp(TheCall))
3125 case Builtin::BI__builtin_setjmp:
3126 if (BuiltinSetjmp(TheCall))
3129 case Builtin::BI__builtin_complex:
3130 if (BuiltinComplex(TheCall))
3133 case Builtin::BI__builtin_classify_type:
3134 case Builtin::BI__builtin_constant_p: {
3143 case Builtin::BI__builtin_launder:
3145 case Builtin::BI__builtin_is_within_lifetime:
3147 case Builtin::BI__builtin_trivially_relocate:
3149 case Builtin::BI__builtin_clear_padding: {
3153 const Expr *PtrArg = TheCall->
getArg(0);
3154 const QualType PtrArgType = PtrArg->
getType();
3157 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3168 diag::err_typecheck_decl_incomplete_type))
3174 auto IsAddrOfDeclExpr = [&]() {
3176 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3177 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3181 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3182 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3186 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3187 if (!VarDecl || VarDecl->getType()->isReferenceType())
3192 QualType VarQType = VarDecl->getType();
3194 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3199 && !IsAddrOfDeclExpr()) {
3200 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3207 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3214 case Builtin::BI__sync_fetch_and_add:
3215 case Builtin::BI__sync_fetch_and_add_1:
3216 case Builtin::BI__sync_fetch_and_add_2:
3217 case Builtin::BI__sync_fetch_and_add_4:
3218 case Builtin::BI__sync_fetch_and_add_8:
3219 case Builtin::BI__sync_fetch_and_add_16:
3220 case Builtin::BI__sync_fetch_and_sub:
3221 case Builtin::BI__sync_fetch_and_sub_1:
3222 case Builtin::BI__sync_fetch_and_sub_2:
3223 case Builtin::BI__sync_fetch_and_sub_4:
3224 case Builtin::BI__sync_fetch_and_sub_8:
3225 case Builtin::BI__sync_fetch_and_sub_16:
3226 case Builtin::BI__sync_fetch_and_or:
3227 case Builtin::BI__sync_fetch_and_or_1:
3228 case Builtin::BI__sync_fetch_and_or_2:
3229 case Builtin::BI__sync_fetch_and_or_4:
3230 case Builtin::BI__sync_fetch_and_or_8:
3231 case Builtin::BI__sync_fetch_and_or_16:
3232 case Builtin::BI__sync_fetch_and_and:
3233 case Builtin::BI__sync_fetch_and_and_1:
3234 case Builtin::BI__sync_fetch_and_and_2:
3235 case Builtin::BI__sync_fetch_and_and_4:
3236 case Builtin::BI__sync_fetch_and_and_8:
3237 case Builtin::BI__sync_fetch_and_and_16:
3238 case Builtin::BI__sync_fetch_and_xor:
3239 case Builtin::BI__sync_fetch_and_xor_1:
3240 case Builtin::BI__sync_fetch_and_xor_2:
3241 case Builtin::BI__sync_fetch_and_xor_4:
3242 case Builtin::BI__sync_fetch_and_xor_8:
3243 case Builtin::BI__sync_fetch_and_xor_16:
3244 case Builtin::BI__sync_fetch_and_nand:
3245 case Builtin::BI__sync_fetch_and_nand_1:
3246 case Builtin::BI__sync_fetch_and_nand_2:
3247 case Builtin::BI__sync_fetch_and_nand_4:
3248 case Builtin::BI__sync_fetch_and_nand_8:
3249 case Builtin::BI__sync_fetch_and_nand_16:
3250 case Builtin::BI__sync_add_and_fetch:
3251 case Builtin::BI__sync_add_and_fetch_1:
3252 case Builtin::BI__sync_add_and_fetch_2:
3253 case Builtin::BI__sync_add_and_fetch_4:
3254 case Builtin::BI__sync_add_and_fetch_8:
3255 case Builtin::BI__sync_add_and_fetch_16:
3256 case Builtin::BI__sync_sub_and_fetch:
3257 case Builtin::BI__sync_sub_and_fetch_1:
3258 case Builtin::BI__sync_sub_and_fetch_2:
3259 case Builtin::BI__sync_sub_and_fetch_4:
3260 case Builtin::BI__sync_sub_and_fetch_8:
3261 case Builtin::BI__sync_sub_and_fetch_16:
3262 case Builtin::BI__sync_and_and_fetch:
3263 case Builtin::BI__sync_and_and_fetch_1:
3264 case Builtin::BI__sync_and_and_fetch_2:
3265 case Builtin::BI__sync_and_and_fetch_4:
3266 case Builtin::BI__sync_and_and_fetch_8:
3267 case Builtin::BI__sync_and_and_fetch_16:
3268 case Builtin::BI__sync_or_and_fetch:
3269 case Builtin::BI__sync_or_and_fetch_1:
3270 case Builtin::BI__sync_or_and_fetch_2:
3271 case Builtin::BI__sync_or_and_fetch_4:
3272 case Builtin::BI__sync_or_and_fetch_8:
3273 case Builtin::BI__sync_or_and_fetch_16:
3274 case Builtin::BI__sync_xor_and_fetch:
3275 case Builtin::BI__sync_xor_and_fetch_1:
3276 case Builtin::BI__sync_xor_and_fetch_2:
3277 case Builtin::BI__sync_xor_and_fetch_4:
3278 case Builtin::BI__sync_xor_and_fetch_8:
3279 case Builtin::BI__sync_xor_and_fetch_16:
3280 case Builtin::BI__sync_nand_and_fetch:
3281 case Builtin::BI__sync_nand_and_fetch_1:
3282 case Builtin::BI__sync_nand_and_fetch_2:
3283 case Builtin::BI__sync_nand_and_fetch_4:
3284 case Builtin::BI__sync_nand_and_fetch_8:
3285 case Builtin::BI__sync_nand_and_fetch_16:
3286 case Builtin::BI__sync_val_compare_and_swap:
3287 case Builtin::BI__sync_val_compare_and_swap_1:
3288 case Builtin::BI__sync_val_compare_and_swap_2:
3289 case Builtin::BI__sync_val_compare_and_swap_4:
3290 case Builtin::BI__sync_val_compare_and_swap_8:
3291 case Builtin::BI__sync_val_compare_and_swap_16:
3292 case Builtin::BI__sync_bool_compare_and_swap:
3293 case Builtin::BI__sync_bool_compare_and_swap_1:
3294 case Builtin::BI__sync_bool_compare_and_swap_2:
3295 case Builtin::BI__sync_bool_compare_and_swap_4:
3296 case Builtin::BI__sync_bool_compare_and_swap_8:
3297 case Builtin::BI__sync_bool_compare_and_swap_16:
3298 case Builtin::BI__sync_lock_test_and_set:
3299 case Builtin::BI__sync_lock_test_and_set_1:
3300 case Builtin::BI__sync_lock_test_and_set_2:
3301 case Builtin::BI__sync_lock_test_and_set_4:
3302 case Builtin::BI__sync_lock_test_and_set_8:
3303 case Builtin::BI__sync_lock_test_and_set_16:
3304 case Builtin::BI__sync_lock_release:
3305 case Builtin::BI__sync_lock_release_1:
3306 case Builtin::BI__sync_lock_release_2:
3307 case Builtin::BI__sync_lock_release_4:
3308 case Builtin::BI__sync_lock_release_8:
3309 case Builtin::BI__sync_lock_release_16:
3310 case Builtin::BI__sync_swap:
3311 case Builtin::BI__sync_swap_1:
3312 case Builtin::BI__sync_swap_2:
3313 case Builtin::BI__sync_swap_4:
3314 case Builtin::BI__sync_swap_8:
3315 case Builtin::BI__sync_swap_16:
3316 return BuiltinAtomicOverloaded(TheCallResult);
3317 case Builtin::BI__sync_synchronize:
3321 case Builtin::BI__builtin_nontemporal_load:
3322 case Builtin::BI__builtin_nontemporal_store:
3323 return BuiltinNontemporalOverloaded(TheCallResult);
3324 case Builtin::BI__builtin_memcpy_inline: {
3325 clang::Expr *SizeOp = TheCall->
getArg(2);
3337 case Builtin::BI__builtin_memset_inline: {
3338 clang::Expr *SizeOp = TheCall->
getArg(2);
3348#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3349 case Builtin::BI##ID: \
3350 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3351#include "clang/Basic/Builtins.inc"
3352 case Builtin::BI__annotation: {
3353 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3354 if (!TT.isOSWindows() && !TT.isUEFI()) {
3363 case Builtin::BI__builtin_annotation:
3367 case Builtin::BI__builtin_addressof:
3371 case Builtin::BI__builtin_function_start:
3375 case Builtin::BI__builtin_is_aligned:
3376 case Builtin::BI__builtin_align_up:
3377 case Builtin::BI__builtin_align_down:
3381 case Builtin::BI__builtin_add_overflow:
3382 case Builtin::BI__builtin_sub_overflow:
3383 case Builtin::BI__builtin_mul_overflow:
3387 case Builtin::BI__builtin_operator_new:
3388 case Builtin::BI__builtin_operator_delete: {
3389 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3391 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3394 case Builtin::BI__builtin_dump_struct:
3396 case Builtin::BI__builtin_expect_with_probability: {
3401 const Expr *ProbArg = TheCall->
getArg(2);
3402 SmallVector<PartialDiagnosticAt, 8> Notes;
3403 Expr::EvalResult Eval;
3407 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3414 bool LoseInfo =
false;
3415 Probability.convert(llvm::APFloat::IEEEdouble(),
3416 llvm::RoundingMode::Dynamic, &LoseInfo);
3417 if (!(Probability >= llvm::APFloat(0.0) &&
3418 Probability <= llvm::APFloat(1.0))) {
3425 case Builtin::BI__builtin_preserve_access_index:
3429 case Builtin::BI__builtin_call_with_static_chain:
3433 case Builtin::BI__exception_code:
3434 case Builtin::BI_exception_code:
3436 diag::err_seh___except_block))
3439 case Builtin::BI__exception_info:
3440 case Builtin::BI_exception_info:
3442 diag::err_seh___except_filter))
3445 case Builtin::BI__GetExceptionInfo:
3457 case Builtin::BIaddressof:
3458 case Builtin::BI__addressof:
3459 case Builtin::BIforward:
3460 case Builtin::BIforward_like:
3461 case Builtin::BImove:
3462 case Builtin::BImove_if_noexcept:
3463 case Builtin::BIas_const: {
3471 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3472 BuiltinID == Builtin::BI__addressof;
3474 (ReturnsPointer ?
Result->isAnyPointerType()
3475 :
Result->isReferenceType()) &&
3478 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3484 case Builtin::BI__builtin_ptrauth_strip:
3486 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3488 case Builtin::BI__builtin_ptrauth_sign_constant:
3491 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3494 case Builtin::BI__builtin_ptrauth_auth:
3497 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3499 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3501 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3503 case Builtin::BI__builtin_ptrauth_string_discriminator:
3506 case Builtin::BI__builtin_get_vtable_pointer:
3510 case Builtin::BIread_pipe:
3511 case Builtin::BIwrite_pipe:
3514 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3517 case Builtin::BIreserve_read_pipe:
3518 case Builtin::BIreserve_write_pipe:
3519 case Builtin::BIwork_group_reserve_read_pipe:
3520 case Builtin::BIwork_group_reserve_write_pipe:
3521 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3524 case Builtin::BIsub_group_reserve_read_pipe:
3525 case Builtin::BIsub_group_reserve_write_pipe:
3526 if (
OpenCL().checkSubgroupExt(TheCall) ||
3527 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3530 case Builtin::BIcommit_read_pipe:
3531 case Builtin::BIcommit_write_pipe:
3532 case Builtin::BIwork_group_commit_read_pipe:
3533 case Builtin::BIwork_group_commit_write_pipe:
3534 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3537 case Builtin::BIsub_group_commit_read_pipe:
3538 case Builtin::BIsub_group_commit_write_pipe:
3539 if (
OpenCL().checkSubgroupExt(TheCall) ||
3540 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3543 case Builtin::BIget_pipe_num_packets:
3544 case Builtin::BIget_pipe_max_packets:
3545 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3548 case Builtin::BIto_global:
3549 case Builtin::BIto_local:
3550 case Builtin::BIto_private:
3551 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3555 case Builtin::BIenqueue_kernel:
3556 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3559 case Builtin::BIget_kernel_work_group_size:
3560 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3561 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3564 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3565 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3566 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3569 case Builtin::BI__builtin_os_log_format:
3570 Cleanup.setExprNeedsCleanups(
true);
3572 case Builtin::BI__builtin_os_log_format_buffer_size:
3573 if (BuiltinOSLogFormat(TheCall))
3576 case Builtin::BI__builtin_frame_address:
3577 case Builtin::BI__builtin_return_address: {
3586 Result.Val.getInt() != 0)
3588 << ((BuiltinID == Builtin::BI__builtin_return_address)
3589 ?
"__builtin_return_address"
3590 :
"__builtin_frame_address")
3595 case Builtin::BI__builtin_nondeterministic_value: {
3596 if (BuiltinNonDeterministicValue(TheCall))
3603 case Builtin::BI__builtin_elementwise_abs:
3611 case Builtin::BI__builtin_elementwise_acos:
3612 case Builtin::BI__builtin_elementwise_asin:
3613 case Builtin::BI__builtin_elementwise_atan:
3614 case Builtin::BI__builtin_elementwise_ceil:
3615 case Builtin::BI__builtin_elementwise_cos:
3616 case Builtin::BI__builtin_elementwise_cosh:
3617 case Builtin::BI__builtin_elementwise_exp:
3618 case Builtin::BI__builtin_elementwise_exp2:
3619 case Builtin::BI__builtin_elementwise_exp10:
3620 case Builtin::BI__builtin_elementwise_floor:
3621 case Builtin::BI__builtin_elementwise_log:
3622 case Builtin::BI__builtin_elementwise_log2:
3623 case Builtin::BI__builtin_elementwise_log10:
3624 case Builtin::BI__builtin_elementwise_roundeven:
3625 case Builtin::BI__builtin_elementwise_round:
3626 case Builtin::BI__builtin_elementwise_rint:
3627 case Builtin::BI__builtin_elementwise_nearbyint:
3628 case Builtin::BI__builtin_elementwise_sin:
3629 case Builtin::BI__builtin_elementwise_sinh:
3630 case Builtin::BI__builtin_elementwise_sqrt:
3631 case Builtin::BI__builtin_elementwise_tan:
3632 case Builtin::BI__builtin_elementwise_tanh:
3633 case Builtin::BI__builtin_elementwise_trunc:
3634 case Builtin::BI__builtin_elementwise_canonicalize:
3639 case Builtin::BI__builtin_elementwise_fma:
3644 case Builtin::BI__builtin_elementwise_ldexp: {
3666 const auto *Vec0 = TyA->
getAs<VectorType>();
3667 const auto *Vec1 = TyExp->
getAs<VectorType>();
3668 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3670 if (Arg0Length != Arg1Length) {
3672 diag::err_typecheck_vector_lengths_not_equal)
3686 case Builtin::BI__builtin_elementwise_minnum:
3687 case Builtin::BI__builtin_elementwise_maxnum:
3688 case Builtin::BI__builtin_elementwise_minimum:
3689 case Builtin::BI__builtin_elementwise_maximum:
3690 case Builtin::BI__builtin_elementwise_minimumnum:
3691 case Builtin::BI__builtin_elementwise_maximumnum:
3692 case Builtin::BI__builtin_elementwise_atan2:
3693 case Builtin::BI__builtin_elementwise_fmod:
3694 case Builtin::BI__builtin_elementwise_pow:
3695 if (BuiltinElementwiseMath(TheCall,
3701 case Builtin::BI__builtin_elementwise_add_sat:
3702 case Builtin::BI__builtin_elementwise_sub_sat:
3703 case Builtin::BI__builtin_elementwise_clmul:
3704 if (BuiltinElementwiseMath(TheCall,
3708 case Builtin::BI__builtin_elementwise_fshl:
3709 case Builtin::BI__builtin_elementwise_fshr:
3714 case Builtin::BI__builtin_elementwise_min:
3715 case Builtin::BI__builtin_elementwise_max: {
3716 if (BuiltinElementwiseMath(TheCall))
3718 Expr *Arg0 = TheCall->
getArg(0);
3719 Expr *Arg1 = TheCall->
getArg(1);
3720 QualType Ty0 = Arg0->
getType();
3721 QualType Ty1 = Arg1->
getType();
3722 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3723 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3726 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3727 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3728 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3731 case Builtin::BI__builtin_elementwise_popcount:
3732 case Builtin::BI__builtin_elementwise_bitreverse:
3737 case Builtin::BI__builtin_elementwise_copysign: {
3746 QualType MagnitudeTy = Magnitude.
get()->
getType();
3759 diag::err_typecheck_call_different_arg_types)
3760 << MagnitudeTy << SignTy;
3768 case Builtin::BI__builtin_elementwise_clzg:
3769 case Builtin::BI__builtin_elementwise_ctzg:
3777 }
else if (BuiltinElementwiseMath(
3781 case Builtin::BI__builtin_reduce_max:
3782 case Builtin::BI__builtin_reduce_min: {
3783 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3786 const Expr *Arg = TheCall->
getArg(0);
3791 ElTy = TyA->getElementType();
3795 if (ElTy.isNull()) {
3805 case Builtin::BI__builtin_reduce_maximum:
3806 case Builtin::BI__builtin_reduce_minimum: {
3807 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3810 const Expr *Arg = TheCall->
getArg(0);
3815 ElTy = TyA->getElementType();
3819 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3832 case Builtin::BI__builtin_reduce_add:
3833 case Builtin::BI__builtin_reduce_mul:
3834 case Builtin::BI__builtin_reduce_xor:
3835 case Builtin::BI__builtin_reduce_or:
3836 case Builtin::BI__builtin_reduce_and: {
3837 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3840 const Expr *Arg = TheCall->
getArg(0);
3854 case Builtin::BI__builtin_reduce_assoc_fadd:
3855 case Builtin::BI__builtin_reduce_in_order_fadd: {
3857 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
3882 diag::err_builtin_invalid_arg_type)
3894 case Builtin::BI__builtin_matrix_transpose:
3895 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3897 case Builtin::BI__builtin_matrix_column_major_load:
3898 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3900 case Builtin::BI__builtin_matrix_column_major_store:
3901 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3903 case Builtin::BI__builtin_verbose_trap:
3908 case Builtin::BI__builtin_get_device_side_mangled_name: {
3909 auto Check = [](CallExpr *TheCall) {
3915 auto *D = DRE->getDecl();
3918 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3919 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3921 if (!Check(TheCall)) {
3923 diag::err_hip_invalid_args_builtin_mangled_name);
3928 case Builtin::BI__builtin_bswapg:
3932 case Builtin::BI__builtin_bitreverseg:
3936 case Builtin::BI__builtin_popcountg:
3940 case Builtin::BI__builtin_clzg:
3941 case Builtin::BI__builtin_ctzg:
3946 case Builtin::BI__builtin_stdc_rotate_left:
3947 case Builtin::BI__builtin_stdc_rotate_right:
3952 case Builtin::BI__builtin_stdc_memreverse8:
3953 case Builtin::BIstdc_memreverse8:
3954 case Builtin::BIstdc_memreverse8u8:
3955 case Builtin::BIstdc_memreverse8u16:
3956 case Builtin::BIstdc_memreverse8u32:
3957 case Builtin::BIstdc_memreverse8u64:
3958 if (
Context.getTargetInfo().getCharWidth() != 8) {
3965 case Builtin::BI__builtin_stdc_bit_floor:
3966 case Builtin::BI__builtin_stdc_bit_ceil:
3970 case Builtin::BI__builtin_stdc_has_single_bit:
3974 case Builtin::BI__builtin_stdc_leading_zeros:
3975 case Builtin::BI__builtin_stdc_leading_ones:
3976 case Builtin::BI__builtin_stdc_trailing_zeros:
3977 case Builtin::BI__builtin_stdc_trailing_ones:
3978 case Builtin::BI__builtin_stdc_first_leading_zero:
3979 case Builtin::BI__builtin_stdc_first_leading_one:
3980 case Builtin::BI__builtin_stdc_first_trailing_zero:
3981 case Builtin::BI__builtin_stdc_first_trailing_one:
3982 case Builtin::BI__builtin_stdc_count_zeros:
3983 case Builtin::BI__builtin_stdc_count_ones:
3984 case Builtin::BI__builtin_stdc_bit_width:
3989 case Builtin::BI__builtin_allow_runtime_check: {
3990 Expr *Arg = TheCall->
getArg(0);
4000 case Builtin::BI__builtin_allow_sanitize_check: {
4004 Expr *Arg = TheCall->
getArg(0);
4006 const StringLiteral *SanitizerName =
4008 if (!SanitizerName) {
4014 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4015 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4016 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4020 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4026 case Builtin::BI__builtin_counted_by_ref:
4027 if (BuiltinCountedByRef(TheCall))
4037 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4038 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4039 assert(
Context.getAuxTargetInfo() &&
4040 "Aux Target Builtin, but not an aux target?");
4042 if (CheckTSBuiltinFunctionCall(
4044 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4047 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4053 return TheCallResult;
4068 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4072 diag::err_argument_not_contiguous_bit_field)
4079 bool IsVariadic =
false;
4082 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4083 IsVariadic = BD->isVariadic();
4084 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4085 IsVariadic = OMD->isVariadic();
4092 bool HasImplicitThisParam,
bool IsVariadic,
4096 else if (IsVariadic)
4106 if (HasImplicitThisParam) {
4138 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4139 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4140 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4141 Expr = ILE->getInit(0);
4151 const Expr *ArgExpr,
4155 S.
PDiag(diag::warn_null_arg)
4161 if (
auto nullability =
type->getNullability())
4172 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4178 llvm::SmallBitVector NonNullArgs;
4184 for (
const auto *Arg : Args)
4191 unsigned IdxAST = Idx.getASTIndex();
4192 if (IdxAST >= Args.size())
4194 if (NonNullArgs.empty())
4195 NonNullArgs.resize(Args.size());
4196 NonNullArgs.set(IdxAST);
4205 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4210 unsigned ParamIndex = 0;
4212 I != E; ++I, ++ParamIndex) {
4215 if (NonNullArgs.empty())
4216 NonNullArgs.resize(Args.size());
4218 NonNullArgs.set(ParamIndex);
4225 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4230 type = blockType->getPointeeType();
4244 if (NonNullArgs.empty())
4245 NonNullArgs.resize(Args.size());
4247 NonNullArgs.set(Index);
4256 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4257 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4258 if (NonNullArgs[ArgIndex])
4264 StringRef ParamName,
QualType ArgTy,
4287 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4288 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4292 if (ArgAlign < ParamAlign)
4293 Diag(Loc, diag::warn_param_mismatched_alignment)
4295 << ParamName << (FDecl !=
nullptr) << FDecl;
4299 const Expr *ThisArg,
4301 if (!FD || Args.empty())
4303 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4304 if (Idx == LifetimeCaptureByAttr::Global ||
4305 Idx == LifetimeCaptureByAttr::Unknown)
4307 if (IsMemberFunction && Idx == 0)
4309 return Args[Idx - IsMemberFunction];
4311 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4316 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4317 for (
int CapturingParamIdx :
Attr->params()) {
4318 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4322 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4325 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4333 I + IsMemberFunction);
4335 if (IsMemberFunction) {
4343 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4353 llvm::any_of(Args, [](
const Expr *E) {
4354 return E && E->isInstantiationDependent();
4359 llvm::SmallBitVector CheckedVarArgs;
4361 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4363 CheckedVarArgs.resize(Args.size());
4364 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4369 CheckedVarArgs.resize(Args.size());
4370 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4377 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4381 : isa_and_nonnull<FunctionDecl>(FDecl)
4383 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4387 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4389 if (
const Expr *Arg = Args[ArgIdx]) {
4390 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4397 if (FDecl || Proto) {
4402 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4403 CheckArgumentWithTypeTag(I, Args, Loc);
4409 if (!Proto && FDecl) {
4411 if (isa_and_nonnull<FunctionProtoType>(FT))
4417 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4419 bool IsScalableArg =
false;
4420 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4422 if (
const Expr *Arg = Args[ArgIdx]) {
4426 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4434 IsScalableArg =
true;
4436 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4445 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4446 llvm::StringMap<bool> CallerFeatureMap;
4447 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4448 if (!CallerFeatureMap.contains(
"sme"))
4449 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4450 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4451 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4460 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4462 (IsScalableArg || IsScalableRet)) {
4463 bool IsCalleeStreaming =
4465 bool IsCalleeStreamingCompatible =
4469 if (!IsCalleeStreamingCompatible &&
4473 unsigned VL = LO.VScaleMin * 128;
4474 unsigned SVL = LO.VScaleStreamingMin * 128;
4475 bool IsVLMismatch = VL && SVL && VL != SVL;
4477 auto EmitDiag = [&](
bool IsArg) {
4481 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4482 << IsArg << IsCalleeStreaming << SVL << VL;
4485 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4486 << IsArg << SVL << VL;
4488 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4505 bool CallerHasZAState =
false;
4506 bool CallerHasZT0State =
false;
4508 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4510 CallerHasZAState =
true;
4512 CallerHasZT0State =
true;
4516 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4518 CallerHasZT0State |=
4520 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4526 Diag(Loc, diag::err_sme_za_call_no_za_state);
4529 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4533 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4534 Diag(Loc, diag::note_sme_use_preserves_za);
4539 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4540 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4541 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4542 if (!Arg->isValueDependent()) {
4544 if (Arg->EvaluateAsInt(Align,
Context)) {
4545 const llvm::APSInt &I = Align.
Val.
getInt();
4546 if (!I.isPowerOf2())
4547 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4548 << Arg->getSourceRange();
4551 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4560 << diag::OffloadLang::SYCL;
4582 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4583 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4585 checkCall(FDecl, Proto,
nullptr, Args,
true,
4594 IsMemberOperatorCall;
4600 Expr *ImplicitThis =
nullptr;
4605 ImplicitThis = Args[0];
4608 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4619 ThisType =
Context.getPointerType(ThisType);
4625 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4643 CheckAbsoluteValueFunction(TheCall, FDecl);
4644 CheckMaxUnsignedZero(TheCall, FDecl);
4645 CheckInfNaNFunction(TheCall, FDecl);
4656 case Builtin::BIstrlcpy:
4657 case Builtin::BIstrlcat:
4658 CheckStrlcpycatArguments(TheCall, FnInfo);
4660 case Builtin::BIstrncat:
4661 CheckStrncatArguments(TheCall, FnInfo);
4663 case Builtin::BIfree:
4664 CheckFreeArguments(TheCall);
4667 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4676 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4677 Ty =
V->getType().getNonReferenceType();
4678 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4679 Ty = F->getType().getNonReferenceType();
4716 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4719 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4721 case AtomicExpr::AO__c11_atomic_init:
4722 case AtomicExpr::AO__opencl_atomic_init:
4723 llvm_unreachable(
"There is no ordering argument for an init");
4725 case AtomicExpr::AO__c11_atomic_load:
4726 case AtomicExpr::AO__opencl_atomic_load:
4727 case AtomicExpr::AO__hip_atomic_load:
4728 case AtomicExpr::AO__atomic_load_n:
4729 case AtomicExpr::AO__atomic_load:
4730 case AtomicExpr::AO__scoped_atomic_load_n:
4731 case AtomicExpr::AO__scoped_atomic_load:
4732 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4733 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4735 case AtomicExpr::AO__c11_atomic_store:
4736 case AtomicExpr::AO__opencl_atomic_store:
4737 case AtomicExpr::AO__hip_atomic_store:
4738 case AtomicExpr::AO__atomic_store:
4739 case AtomicExpr::AO__atomic_store_n:
4740 case AtomicExpr::AO__scoped_atomic_store:
4741 case AtomicExpr::AO__scoped_atomic_store_n:
4742 case AtomicExpr::AO__atomic_clear:
4743 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4744 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4745 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4775#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4776 case AtomicExpr::AO__hip_atomic_##hip: \
4777 OldName = "__hip_atomic_" #hip; \
4778 NewName = "__scoped_atomic_" #scoped; \
4791#undef HIP_ATOMIC_FIXABLE
4792 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4793 OldName =
"__hip_atomic_compare_exchange_weak";
4794 NewName =
"__scoped_atomic_compare_exchange";
4797 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4798 OldName =
"__hip_atomic_compare_exchange_strong";
4799 NewName =
"__scoped_atomic_compare_exchange";
4803 llvm_unreachable(
"unhandled HIP atomic op");
4806 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4807 << OldName << NewName;
4814 std::optional<llvm::APSInt> ScopeVal =
4819 StringRef ScopeName;
4820 switch (ScopeVal->getZExtValue()) {
4822 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4825 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4828 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4831 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4834 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
4837 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
4889 const unsigned NumForm = ClearByte + 1;
4890 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4891 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4899 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4900 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4901 "need to update code for modified forms");
4902 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4903 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4904 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4905 "need to update code for modified C11 atomics");
4906 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4907 Op <= AtomicExpr::AO__opencl_atomic_store;
4908 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4909 Op <= AtomicExpr::AO__hip_atomic_store;
4910 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4911 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4912 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4913 Op <= AtomicExpr::AO__c11_atomic_store) ||
4915 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4916 Op == AtomicExpr::AO__atomic_store_n ||
4917 Op == AtomicExpr::AO__atomic_exchange_n ||
4918 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4919 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4920 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4921 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4922 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4926 enum ArithOpExtraValueType {
4931 unsigned ArithAllows = AOEVT_None;
4934 case AtomicExpr::AO__c11_atomic_init:
4935 case AtomicExpr::AO__opencl_atomic_init:
4939 case AtomicExpr::AO__c11_atomic_load:
4940 case AtomicExpr::AO__opencl_atomic_load:
4941 case AtomicExpr::AO__hip_atomic_load:
4942 case AtomicExpr::AO__atomic_load_n:
4943 case AtomicExpr::AO__scoped_atomic_load_n:
4944 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4948 case AtomicExpr::AO__atomic_load:
4949 case AtomicExpr::AO__scoped_atomic_load:
4950 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4954 case AtomicExpr::AO__c11_atomic_store:
4955 case AtomicExpr::AO__opencl_atomic_store:
4956 case AtomicExpr::AO__hip_atomic_store:
4957 case AtomicExpr::AO__atomic_store:
4958 case AtomicExpr::AO__atomic_store_n:
4959 case AtomicExpr::AO__scoped_atomic_store:
4960 case AtomicExpr::AO__scoped_atomic_store_n:
4961 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4964 case AtomicExpr::AO__atomic_fetch_add:
4965 case AtomicExpr::AO__atomic_fetch_sub:
4966 case AtomicExpr::AO__atomic_add_fetch:
4967 case AtomicExpr::AO__atomic_sub_fetch:
4968 case AtomicExpr::AO__scoped_atomic_fetch_add:
4969 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4970 case AtomicExpr::AO__scoped_atomic_add_fetch:
4971 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4972 case AtomicExpr::AO__c11_atomic_fetch_add:
4973 case AtomicExpr::AO__c11_atomic_fetch_sub:
4974 case AtomicExpr::AO__opencl_atomic_fetch_add:
4975 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4976 case AtomicExpr::AO__hip_atomic_fetch_add:
4977 case AtomicExpr::AO__hip_atomic_fetch_sub:
4978 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4981 case AtomicExpr::AO__atomic_fetch_max:
4982 case AtomicExpr::AO__atomic_fetch_min:
4983 case AtomicExpr::AO__atomic_max_fetch:
4984 case AtomicExpr::AO__atomic_min_fetch:
4985 case AtomicExpr::AO__scoped_atomic_fetch_max:
4986 case AtomicExpr::AO__scoped_atomic_fetch_min:
4987 case AtomicExpr::AO__scoped_atomic_max_fetch:
4988 case AtomicExpr::AO__scoped_atomic_min_fetch:
4989 case AtomicExpr::AO__c11_atomic_fetch_max:
4990 case AtomicExpr::AO__c11_atomic_fetch_min:
4991 case AtomicExpr::AO__opencl_atomic_fetch_max:
4992 case AtomicExpr::AO__opencl_atomic_fetch_min:
4993 case AtomicExpr::AO__hip_atomic_fetch_max:
4994 case AtomicExpr::AO__hip_atomic_fetch_min:
4995 ArithAllows = AOEVT_FP;
4998 case AtomicExpr::AO__c11_atomic_fetch_and:
4999 case AtomicExpr::AO__c11_atomic_fetch_or:
5000 case AtomicExpr::AO__c11_atomic_fetch_xor:
5001 case AtomicExpr::AO__hip_atomic_fetch_and:
5002 case AtomicExpr::AO__hip_atomic_fetch_or:
5003 case AtomicExpr::AO__hip_atomic_fetch_xor:
5004 case AtomicExpr::AO__c11_atomic_fetch_nand:
5005 case AtomicExpr::AO__opencl_atomic_fetch_and:
5006 case AtomicExpr::AO__opencl_atomic_fetch_or:
5007 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5008 case AtomicExpr::AO__atomic_fetch_and:
5009 case AtomicExpr::AO__atomic_fetch_or:
5010 case AtomicExpr::AO__atomic_fetch_xor:
5011 case AtomicExpr::AO__atomic_fetch_nand:
5012 case AtomicExpr::AO__atomic_and_fetch:
5013 case AtomicExpr::AO__atomic_or_fetch:
5014 case AtomicExpr::AO__atomic_xor_fetch:
5015 case AtomicExpr::AO__atomic_nand_fetch:
5016 case AtomicExpr::AO__atomic_fetch_uinc:
5017 case AtomicExpr::AO__atomic_fetch_udec:
5018 case AtomicExpr::AO__scoped_atomic_fetch_and:
5019 case AtomicExpr::AO__scoped_atomic_fetch_or:
5020 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5021 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5022 case AtomicExpr::AO__scoped_atomic_and_fetch:
5023 case AtomicExpr::AO__scoped_atomic_or_fetch:
5024 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5025 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5026 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5027 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5031 case AtomicExpr::AO__c11_atomic_exchange:
5032 case AtomicExpr::AO__hip_atomic_exchange:
5033 case AtomicExpr::AO__opencl_atomic_exchange:
5034 case AtomicExpr::AO__atomic_exchange_n:
5035 case AtomicExpr::AO__scoped_atomic_exchange_n:
5036 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5040 case AtomicExpr::AO__atomic_exchange:
5041 case AtomicExpr::AO__scoped_atomic_exchange:
5042 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5046 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5047 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5048 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5049 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5050 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5051 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5055 case AtomicExpr::AO__atomic_compare_exchange:
5056 case AtomicExpr::AO__atomic_compare_exchange_n:
5057 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5058 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5059 ArithAllows = AOEVT_Pointer;
5063 case AtomicExpr::AO__atomic_test_and_set:
5064 Form = TestAndSetByte;
5067 case AtomicExpr::AO__atomic_clear:
5072 unsigned AdjustedNumArgs = NumArgs[Form];
5073 if ((IsOpenCL || IsHIP || IsScoped) &&
5074 Op != AtomicExpr::AO__opencl_atomic_init)
5077 if (Args.size() < AdjustedNumArgs) {
5078 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5079 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5082 }
else if (Args.size() > AdjustedNumArgs) {
5083 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5084 diag::err_typecheck_call_too_many_args)
5085 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5091 Expr *Ptr = Args[0];
5096 Ptr = ConvertedPtr.
get();
5099 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5109 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5115 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5121 }
else if (Form != Load && Form != LoadCopy) {
5123 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5129 if (Form != TestAndSetByte && Form != ClearByte) {
5132 diag::err_incomplete_type))
5135 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5136 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5146 pointerType->getPointeeType().getCVRQualifiers());
5156 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5166 auto IsAllowedValueType = [&](
QualType ValType,
5167 unsigned AllowedType) ->
bool {
5168 bool IsX87LongDouble =
5170 &
Context.getTargetInfo().getLongDoubleFormat() ==
5171 &llvm::APFloat::x87DoubleExtended();
5175 return AllowedType & AOEVT_Pointer;
5179 if (IsX87LongDouble)
5183 if (!IsAllowedValueType(ValType, ArithAllows)) {
5184 auto DID = ArithAllows & AOEVT_FP
5185 ? (ArithAllows & AOEVT_Pointer
5186 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5187 : diag::err_atomic_op_needs_atomic_int_or_fp)
5188 : (ArithAllows & AOEVT_Pointer
5189 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5190 : diag::err_atomic_op_needs_atomic_int);
5197 diag::err_incomplete_type)) {
5208 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5224 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5236 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5239 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5245 bool IsPassedByAddress =
false;
5246 if (!IsC11 && !IsHIP && !IsN) {
5248 IsPassedByAddress =
true;
5253 APIOrderedArgs.push_back(Args[0]);
5257 APIOrderedArgs.push_back(Args[1]);
5263 APIOrderedArgs.push_back(Args[2]);
5264 APIOrderedArgs.push_back(Args[1]);
5267 APIOrderedArgs.push_back(Args[2]);
5268 APIOrderedArgs.push_back(Args[3]);
5269 APIOrderedArgs.push_back(Args[1]);
5272 APIOrderedArgs.push_back(Args[2]);
5273 APIOrderedArgs.push_back(Args[4]);
5274 APIOrderedArgs.push_back(Args[1]);
5275 APIOrderedArgs.push_back(Args[3]);
5278 APIOrderedArgs.push_back(Args[2]);
5279 APIOrderedArgs.push_back(Args[4]);
5280 APIOrderedArgs.push_back(Args[5]);
5281 APIOrderedArgs.push_back(Args[1]);
5282 APIOrderedArgs.push_back(Args[3]);
5284 case TestAndSetByte:
5286 APIOrderedArgs.push_back(Args[1]);
5290 APIOrderedArgs.append(Args.begin(), Args.end());
5297 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5299 if (i < NumVals[Form] + 1) {
5312 assert(Form != Load);
5314 Ty =
Context.getPointerDiffType();
5317 else if (Form ==
Copy || Form == Xchg) {
5318 if (IsPassedByAddress) {
5325 Expr *ValArg = APIOrderedArgs[i];
5332 AS = PtrTy->getPointeeType().getAddressSpace();
5341 if (IsPassedByAddress)
5361 APIOrderedArgs[i] = Arg.
get();
5366 SubExprs.push_back(Ptr);
5370 SubExprs.push_back(APIOrderedArgs[1]);
5373 case TestAndSetByte:
5375 SubExprs.push_back(APIOrderedArgs[1]);
5381 SubExprs.push_back(APIOrderedArgs[2]);
5382 SubExprs.push_back(APIOrderedArgs[1]);
5386 SubExprs.push_back(APIOrderedArgs[3]);
5387 SubExprs.push_back(APIOrderedArgs[1]);
5388 SubExprs.push_back(APIOrderedArgs[2]);
5391 SubExprs.push_back(APIOrderedArgs[3]);
5392 SubExprs.push_back(APIOrderedArgs[1]);
5393 SubExprs.push_back(APIOrderedArgs[4]);
5394 SubExprs.push_back(APIOrderedArgs[2]);
5397 SubExprs.push_back(APIOrderedArgs[4]);
5398 SubExprs.push_back(APIOrderedArgs[1]);
5399 SubExprs.push_back(APIOrderedArgs[5]);
5400 SubExprs.push_back(APIOrderedArgs[2]);
5401 SubExprs.push_back(APIOrderedArgs[3]);
5406 if (SubExprs.size() >= 2 && Form !=
Init) {
5407 std::optional<llvm::APSInt>
Success =
5408 SubExprs[1]->getIntegerConstantExpr(
Context);
5410 Diag(SubExprs[1]->getBeginLoc(),
5411 diag::warn_atomic_op_has_invalid_memory_order)
5412 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5413 << SubExprs[1]->getSourceRange();
5415 if (SubExprs.size() >= 5) {
5416 if (std::optional<llvm::APSInt>
Failure =
5417 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5418 if (!llvm::is_contained(
5419 {llvm::AtomicOrderingCABI::relaxed,
5420 llvm::AtomicOrderingCABI::consume,
5421 llvm::AtomicOrderingCABI::acquire,
5422 llvm::AtomicOrderingCABI::seq_cst},
5423 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5424 Diag(SubExprs[3]->getBeginLoc(),
5425 diag::warn_atomic_op_has_invalid_memory_order)
5426 << 2 << SubExprs[3]->getSourceRange();
5433 auto *
Scope = Args[Args.size() - 1];
5434 if (std::optional<llvm::APSInt>
Result =
5436 if (!ScopeModel->isValid(
Result->getZExtValue()))
5437 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5438 <<
Scope->getSourceRange();
5440 SubExprs.push_back(
Scope);
5449 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5450 Op == AtomicExpr::AO__c11_atomic_store ||
5451 Op == AtomicExpr::AO__opencl_atomic_load ||
5452 Op == AtomicExpr::AO__hip_atomic_load ||
5453 Op == AtomicExpr::AO__opencl_atomic_store ||
5454 Op == AtomicExpr::AO__hip_atomic_store) &&
5455 Context.AtomicUsesUnsupportedLibcall(AE))
5457 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5458 Op == AtomicExpr::AO__opencl_atomic_load ||
5459 Op == AtomicExpr::AO__hip_atomic_load)
5464 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5480 assert(Fn &&
"builtin call without direct callee!");
5496 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5503 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5505 <<
Callee->getSourceRange();
5514 Expr *FirstArg = TheCall->
getArg(0);
5518 FirstArg = FirstArgResult.
get();
5519 TheCall->
setArg(0, FirstArg);
5531 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5538 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5568 QualType ResultType = ValType;
5573#define BUILTIN_ROW(x) \
5574 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5575 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5577 static const unsigned BuiltinIndices[][5] = {
5602 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5603 case 1: SizeIndex = 0;
break;
5604 case 2: SizeIndex = 1;
break;
5605 case 4: SizeIndex = 2;
break;
5606 case 8: SizeIndex = 3;
break;
5607 case 16: SizeIndex = 4;
break;
5619 unsigned BuiltinIndex, NumFixed = 1;
5620 bool WarnAboutSemanticsChange =
false;
5621 switch (BuiltinID) {
5622 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5623 case Builtin::BI__sync_fetch_and_add:
5624 case Builtin::BI__sync_fetch_and_add_1:
5625 case Builtin::BI__sync_fetch_and_add_2:
5626 case Builtin::BI__sync_fetch_and_add_4:
5627 case Builtin::BI__sync_fetch_and_add_8:
5628 case Builtin::BI__sync_fetch_and_add_16:
5632 case Builtin::BI__sync_fetch_and_sub:
5633 case Builtin::BI__sync_fetch_and_sub_1:
5634 case Builtin::BI__sync_fetch_and_sub_2:
5635 case Builtin::BI__sync_fetch_and_sub_4:
5636 case Builtin::BI__sync_fetch_and_sub_8:
5637 case Builtin::BI__sync_fetch_and_sub_16:
5641 case Builtin::BI__sync_fetch_and_or:
5642 case Builtin::BI__sync_fetch_and_or_1:
5643 case Builtin::BI__sync_fetch_and_or_2:
5644 case Builtin::BI__sync_fetch_and_or_4:
5645 case Builtin::BI__sync_fetch_and_or_8:
5646 case Builtin::BI__sync_fetch_and_or_16:
5650 case Builtin::BI__sync_fetch_and_and:
5651 case Builtin::BI__sync_fetch_and_and_1:
5652 case Builtin::BI__sync_fetch_and_and_2:
5653 case Builtin::BI__sync_fetch_and_and_4:
5654 case Builtin::BI__sync_fetch_and_and_8:
5655 case Builtin::BI__sync_fetch_and_and_16:
5659 case Builtin::BI__sync_fetch_and_xor:
5660 case Builtin::BI__sync_fetch_and_xor_1:
5661 case Builtin::BI__sync_fetch_and_xor_2:
5662 case Builtin::BI__sync_fetch_and_xor_4:
5663 case Builtin::BI__sync_fetch_and_xor_8:
5664 case Builtin::BI__sync_fetch_and_xor_16:
5668 case Builtin::BI__sync_fetch_and_nand:
5669 case Builtin::BI__sync_fetch_and_nand_1:
5670 case Builtin::BI__sync_fetch_and_nand_2:
5671 case Builtin::BI__sync_fetch_and_nand_4:
5672 case Builtin::BI__sync_fetch_and_nand_8:
5673 case Builtin::BI__sync_fetch_and_nand_16:
5675 WarnAboutSemanticsChange =
true;
5678 case Builtin::BI__sync_add_and_fetch:
5679 case Builtin::BI__sync_add_and_fetch_1:
5680 case Builtin::BI__sync_add_and_fetch_2:
5681 case Builtin::BI__sync_add_and_fetch_4:
5682 case Builtin::BI__sync_add_and_fetch_8:
5683 case Builtin::BI__sync_add_and_fetch_16:
5687 case Builtin::BI__sync_sub_and_fetch:
5688 case Builtin::BI__sync_sub_and_fetch_1:
5689 case Builtin::BI__sync_sub_and_fetch_2:
5690 case Builtin::BI__sync_sub_and_fetch_4:
5691 case Builtin::BI__sync_sub_and_fetch_8:
5692 case Builtin::BI__sync_sub_and_fetch_16:
5696 case Builtin::BI__sync_and_and_fetch:
5697 case Builtin::BI__sync_and_and_fetch_1:
5698 case Builtin::BI__sync_and_and_fetch_2:
5699 case Builtin::BI__sync_and_and_fetch_4:
5700 case Builtin::BI__sync_and_and_fetch_8:
5701 case Builtin::BI__sync_and_and_fetch_16:
5705 case Builtin::BI__sync_or_and_fetch:
5706 case Builtin::BI__sync_or_and_fetch_1:
5707 case Builtin::BI__sync_or_and_fetch_2:
5708 case Builtin::BI__sync_or_and_fetch_4:
5709 case Builtin::BI__sync_or_and_fetch_8:
5710 case Builtin::BI__sync_or_and_fetch_16:
5714 case Builtin::BI__sync_xor_and_fetch:
5715 case Builtin::BI__sync_xor_and_fetch_1:
5716 case Builtin::BI__sync_xor_and_fetch_2:
5717 case Builtin::BI__sync_xor_and_fetch_4:
5718 case Builtin::BI__sync_xor_and_fetch_8:
5719 case Builtin::BI__sync_xor_and_fetch_16:
5723 case Builtin::BI__sync_nand_and_fetch:
5724 case Builtin::BI__sync_nand_and_fetch_1:
5725 case Builtin::BI__sync_nand_and_fetch_2:
5726 case Builtin::BI__sync_nand_and_fetch_4:
5727 case Builtin::BI__sync_nand_and_fetch_8:
5728 case Builtin::BI__sync_nand_and_fetch_16:
5730 WarnAboutSemanticsChange =
true;
5733 case Builtin::BI__sync_val_compare_and_swap:
5734 case Builtin::BI__sync_val_compare_and_swap_1:
5735 case Builtin::BI__sync_val_compare_and_swap_2:
5736 case Builtin::BI__sync_val_compare_and_swap_4:
5737 case Builtin::BI__sync_val_compare_and_swap_8:
5738 case Builtin::BI__sync_val_compare_and_swap_16:
5743 case Builtin::BI__sync_bool_compare_and_swap:
5744 case Builtin::BI__sync_bool_compare_and_swap_1:
5745 case Builtin::BI__sync_bool_compare_and_swap_2:
5746 case Builtin::BI__sync_bool_compare_and_swap_4:
5747 case Builtin::BI__sync_bool_compare_and_swap_8:
5748 case Builtin::BI__sync_bool_compare_and_swap_16:
5754 case Builtin::BI__sync_lock_test_and_set:
5755 case Builtin::BI__sync_lock_test_and_set_1:
5756 case Builtin::BI__sync_lock_test_and_set_2:
5757 case Builtin::BI__sync_lock_test_and_set_4:
5758 case Builtin::BI__sync_lock_test_and_set_8:
5759 case Builtin::BI__sync_lock_test_and_set_16:
5763 case Builtin::BI__sync_lock_release:
5764 case Builtin::BI__sync_lock_release_1:
5765 case Builtin::BI__sync_lock_release_2:
5766 case Builtin::BI__sync_lock_release_4:
5767 case Builtin::BI__sync_lock_release_8:
5768 case Builtin::BI__sync_lock_release_16:
5774 case Builtin::BI__sync_swap:
5775 case Builtin::BI__sync_swap_1:
5776 case Builtin::BI__sync_swap_2:
5777 case Builtin::BI__sync_swap_4:
5778 case Builtin::BI__sync_swap_8:
5779 case Builtin::BI__sync_swap_16:
5787 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5788 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5789 <<
Callee->getSourceRange();
5793 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5794 <<
Callee->getSourceRange();
5796 if (WarnAboutSemanticsChange) {
5797 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5798 <<
Callee->getSourceRange();
5803 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5804 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5805 FunctionDecl *NewBuiltinDecl;
5806 if (NewBuiltinID == BuiltinID)
5807 NewBuiltinDecl = FDecl;
5810 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5813 assert(Res.getFoundDecl());
5814 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5815 if (!NewBuiltinDecl)
5822 for (
unsigned i = 0; i != NumFixed; ++i) {
5851 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5853 CK_BuiltinFnToFnPtr);
5864 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5865 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5866 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5870 return TheCallResult;
5874 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5879 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5880 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5881 "Unexpected nontemporal load/store builtin!");
5882 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5883 unsigned numArgs = isStore ? 2 : 1;
5893 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5899 PointerArg = PointerArgResult.
get();
5900 TheCall->
setArg(numArgs - 1, PointerArg);
5904 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5917 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5924 return TheCallResult;
5936 return TheCallResult;
5943 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5945 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5946 Literal = ObjcLiteral->getString();
5950 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5957 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5958 InitializedEntity Entity =
5968 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5969 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5970 TT.getArch() == llvm::Triple::aarch64_32);
5971 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5972 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5973 if (IsX64 || IsAArch64) {
5980 return S.
Diag(Fn->getBeginLoc(),
5981 diag::err_ms_va_start_used_in_sysv_function);
5988 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5989 return S.
Diag(Fn->getBeginLoc(),
5990 diag::err_va_start_used_in_wrong_abi_function)
5991 << !IsWindowsOrUEFI;
5997 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6005 bool IsVariadic =
false;
6008 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6009 IsVariadic =
Block->isVariadic();
6010 Params =
Block->parameters();
6011 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6014 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6015 IsVariadic = MD->isVariadic();
6017 Params = MD->parameters();
6020 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6024 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6029 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6034 *LastParam = Params.empty() ?
nullptr : Params.back();
6039bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6044 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6068 ParmVarDecl *LastParam;
6079 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6081 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6086 if (std::optional<llvm::APSInt> Val =
6088 Val &&
LangOpts.C23 && *Val == 0 &&
6089 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6090 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6097 SourceLocation ParamLoc;
6098 bool IsCRegister =
false;
6099 bool SecondArgIsLastNonVariadicArgument =
false;
6100 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6101 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6102 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6105 ParamLoc = PV->getLocation();
6111 if (!SecondArgIsLastNonVariadicArgument)
6113 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6114 else if (IsCRegister ||
Type->isReferenceType() ||
6115 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6118 if (!Context.isPromotableIntegerType(Type))
6120 const auto *ED = Type->getAsEnumDecl();
6123 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6125 unsigned Reason = 0;
6126 if (
Type->isReferenceType()) Reason = 1;
6127 else if (IsCRegister) Reason = 2;
6128 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6129 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6136 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6156 if (
Call->getNumArgs() < 3)
6158 diag::err_typecheck_call_too_few_args_at_least)
6159 << 0 << 3 <<
Call->getNumArgs()
6175 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6178 const QualType &ConstCharPtrTy =
6180 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6182 << Arg1->
getType() << ConstCharPtrTy << 1
6185 << 2 << Arg1->
getType() << ConstCharPtrTy;
6187 const QualType SizeTy =
Context.getSizeType();
6192 << Arg2->
getType() << SizeTy << 1
6195 << 3 << Arg2->
getType() << SizeTy;
6200bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6204 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6232 diag::err_typecheck_call_invalid_ordered_compare)
6240bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6241 unsigned BuiltinID) {
6246 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6247 BuiltinID == Builtin::BI__builtin_isinf ||
6248 BuiltinID == Builtin::BI__builtin_isinf_sign))
6252 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6253 BuiltinID == Builtin::BI__builtin_isunordered))
6257 bool IsFPClass = NumArgs == 2;
6260 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6264 for (
unsigned i = 0; i < FPArgNo; ++i) {
6265 Expr *Arg = TheCall->
getArg(i);
6278 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6286 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
6291 OrigArg = Res.
get();
6297 OrigArg = Res.
get();
6299 TheCall->
setArg(FPArgNo, OrigArg);
6301 QualType VectorResultTy;
6302 QualType ElementTy = OrigArg->
getType();
6307 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6313 diag::err_typecheck_call_invalid_unary_fp)
6325 if (!VectorResultTy.
isNull())
6326 ResultTy = VectorResultTy;
6335bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6340 for (
unsigned I = 0; I != 2; ++I) {
6341 Expr *Arg = TheCall->
getArg(I);
6351 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6366 Expr *Real = TheCall->
getArg(0);
6367 Expr *Imag = TheCall->
getArg(1);
6370 diag::err_typecheck_call_different_arg_types)
6385 diag::err_typecheck_call_too_few_args_at_least)
6386 << 0 << 2 << NumArgs
6393 unsigned NumElements = 0;
6408 unsigned NumResElements = NumArgs - 2;
6417 diag::err_vec_builtin_incompatible_vector)
6422 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6424 diag::err_vec_builtin_incompatible_vector)
6429 }
else if (NumElements != NumResElements) {
6432 ?
Context.getExtVectorType(EltType, NumResElements)
6433 :
Context.getVectorType(EltType, NumResElements,
6438 for (
unsigned I = 2; I != NumArgs; ++I) {
6446 diag::err_shufflevector_nonconstant_argument)
6452 else if (
Result->getActiveBits() > 64 ||
6453 Result->getZExtValue() >= NumElements * 2)
6455 diag::err_shufflevector_argument_too_large)
6480 diag::err_convertvector_non_vector)
6483 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6485 <<
"__builtin_convertvector");
6490 if (SrcElts != DstElts)
6492 diag::err_convertvector_incompatible_vector)
6500bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6505 diag::err_typecheck_call_too_many_args_at_most)
6506 << 0 << 3 << NumArgs << 0
6511 for (
unsigned i = 1; i != NumArgs; ++i)
6518bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6519 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6520 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6530 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6540bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6541 Expr *Arg = TheCall->
getArg(0);
6552bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6554 Expr *Arg = TheCall->
getArg(1);
6558 if (
const auto *UE =
6560 if (UE->getKind() == UETT_AlignOf ||
6561 UE->getKind() == UETT_PreferredAlignOf)
6567 if (!
Result.isPowerOf2())
6568 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6575 if (
Result > std::numeric_limits<int32_t>::max())
6583bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6588 Expr *FirstArg = TheCall->
getArg(0);
6594 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6598 TheCall->
setArg(0, FirstArgResult.
get());
6602 Expr *SecondArg = TheCall->
getArg(1);
6610 if (!
Result.isPowerOf2())
6611 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6623 Expr *ThirdArg = TheCall->
getArg(2);
6626 TheCall->
setArg(2, ThirdArg);
6632bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6633 unsigned BuiltinID =
6635 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6638 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6639 if (NumArgs < NumRequiredArgs) {
6640 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6641 << 0 << NumRequiredArgs << NumArgs
6644 if (NumArgs >= NumRequiredArgs + 0x100) {
6646 diag::err_typecheck_call_too_many_args_at_most)
6647 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6658 if (Arg.isInvalid())
6660 TheCall->
setArg(i, Arg.get());
6665 unsigned FormatIdx = i;
6675 unsigned FirstDataArg = i;
6676 while (i < NumArgs) {
6694 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6696 bool Success = CheckFormatArguments(
6699 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6723 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6732 int High,
bool RangeIsError) {
6746 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6754 PDiag(diag::warn_argument_invalid_range)
6797 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6802 if (
Value.isNegative())
6813 if ((
Value & 0xFF) != 0)
6838 Result.setIsUnsigned(
true);
6843 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6863 Result.setIsUnsigned(
true);
6871 diag::err_argument_not_shifted_byte_or_xxff)
6875bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6876 if (!Context.getTargetInfo().hasSjLjLowering())
6877 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6888 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6894bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6895 if (!Context.getTargetInfo().hasSjLjLowering())
6896 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6901bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6916 diag::err_builtin_counted_by_ref_invalid_arg)
6921 diag::err_builtin_counted_by_ref_has_side_effects)
6924 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6926 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6931 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6938 QualType MemberTy = ME->getMemberDecl()->getType();
6941 diag::err_builtin_counted_by_ref_invalid_arg)
6945 diag::err_builtin_counted_by_ref_invalid_arg)
6955bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6957 const CallExpr *CE =
6966 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6971 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6976 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6980 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6984 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6994class UncoveredArgHandler {
6995 enum {
Unknown = -1, AllCovered = -2 };
6997 signed FirstUncoveredArg =
Unknown;
6998 SmallVector<const Expr *, 4> DiagnosticExprs;
7001 UncoveredArgHandler() =
default;
7003 bool hasUncoveredArg()
const {
7004 return (FirstUncoveredArg >= 0);
7007 unsigned getUncoveredArg()
const {
7008 assert(hasUncoveredArg() &&
"no uncovered argument");
7009 return FirstUncoveredArg;
7012 void setAllCovered() {
7015 DiagnosticExprs.clear();
7016 FirstUncoveredArg = AllCovered;
7019 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7020 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7023 if (FirstUncoveredArg == AllCovered)
7028 if (NewFirstUncoveredArg == FirstUncoveredArg)
7029 DiagnosticExprs.push_back(StrExpr);
7030 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7031 DiagnosticExprs.clear();
7032 DiagnosticExprs.push_back(StrExpr);
7033 FirstUncoveredArg = NewFirstUncoveredArg;
7037 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7040enum StringLiteralCheckType {
7042 SLCT_UncheckedLiteral,
7050 bool AddendIsRight) {
7051 unsigned BitWidth = Offset.getBitWidth();
7052 unsigned AddendBitWidth = Addend.getBitWidth();
7054 if (Addend.isUnsigned()) {
7055 Addend = Addend.zext(++AddendBitWidth);
7056 Addend.setIsSigned(
true);
7059 if (AddendBitWidth > BitWidth) {
7060 Offset = Offset.sext(AddendBitWidth);
7061 BitWidth = AddendBitWidth;
7062 }
else if (BitWidth > AddendBitWidth) {
7063 Addend = Addend.sext(BitWidth);
7067 llvm::APSInt ResOffset = Offset;
7068 if (BinOpKind == BO_Add)
7069 ResOffset = Offset.sadd_ov(Addend, Ov);
7071 assert(AddendIsRight && BinOpKind == BO_Sub &&
7072 "operator must be add or sub with addend on the right");
7073 ResOffset = Offset.ssub_ov(Addend, Ov);
7079 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7080 "index (intermediate) result too big");
7081 Offset = Offset.sext(2 * BitWidth);
7082 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7086 Offset = std::move(ResOffset);
7094class FormatStringLiteral {
7095 const StringLiteral *FExpr;
7099 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7100 : FExpr(fexpr), Offset(Offset) {}
7102 const StringLiteral *getFormatString()
const {
return FExpr; }
7104 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7106 unsigned getByteLength()
const {
7107 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7110 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7117 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7118 bool isWide()
const {
return FExpr->
isWide(); }
7119 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7120 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7121 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7122 bool isPascal()
const {
return FExpr->
isPascal(); }
7124 SourceLocation getLocationOfByte(
7125 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
7126 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7127 unsigned *StartTokenByteOffset =
nullptr)
const {
7129 StartToken, StartTokenByteOffset);
7132 SourceLocation getBeginLoc() const LLVM_READONLY {
7136 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7142 Sema &S,
const FormatStringLiteral *FExpr,
7147 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7148 bool IgnoreStringsWithoutSpecifiers);
7157static StringLiteralCheckType
7163 llvm::SmallBitVector &CheckedVarArgs,
7164 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7165 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7166 bool IgnoreStringsWithoutSpecifiers =
false) {
7168 return SLCT_NotALiteral;
7170 assert(Offset.isSigned() &&
"invalid offset");
7173 return SLCT_NotALiteral;
7182 return SLCT_UncheckedLiteral;
7185 case Stmt::InitListExprClass:
7189 format_idx, firstDataArg,
Type, CallType,
7190 false, CheckedVarArgs,
7191 UncoveredArg, Offset, CallerFormatParamIdx,
7192 IgnoreStringsWithoutSpecifiers);
7194 return SLCT_NotALiteral;
7195 case Stmt::BinaryConditionalOperatorClass:
7196 case Stmt::ConditionalOperatorClass: {
7205 bool CheckLeft =
true, CheckRight =
true;
7208 if (
C->getCond()->EvaluateAsBooleanCondition(
7220 StringLiteralCheckType Left;
7222 Left = SLCT_UncheckedLiteral;
7225 Args, APK, format_idx, firstDataArg,
Type,
7226 CallType, InFunctionCall, CheckedVarArgs,
7227 UncoveredArg, Offset, CallerFormatParamIdx,
7228 IgnoreStringsWithoutSpecifiers);
7229 if (Left == SLCT_NotALiteral || !CheckRight) {
7235 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7236 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7237 UncoveredArg, Offset, CallerFormatParamIdx,
7238 IgnoreStringsWithoutSpecifiers);
7240 return (CheckLeft && Left < Right) ? Left : Right;
7243 case Stmt::ImplicitCastExprClass:
7247 case Stmt::OpaqueValueExprClass:
7252 return SLCT_NotALiteral;
7254 case Stmt::PredefinedExprClass:
7258 return SLCT_UncheckedLiteral;
7260 case Stmt::DeclRefExprClass: {
7266 bool isConstant =
false;
7270 isConstant = AT->getElementType().isConstant(S.
Context);
7272 isConstant = T.isConstant(S.
Context) &&
7273 PT->getPointeeType().isConstant(S.
Context);
7274 }
else if (T->isObjCObjectPointerType()) {
7277 isConstant = T.isConstant(S.
Context);
7281 if (
const Expr *
Init = VD->getAnyInitializer()) {
7284 if (InitList->isStringLiteralInit())
7285 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7288 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7289 firstDataArg,
Type, CallType,
false,
7290 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7341 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7342 if (CallerFormatParamIdx)
7343 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7344 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7345 for (
const auto *PVFormatMatches :
7346 D->specific_attrs<FormatMatchesAttr>()) {
7351 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7355 S.
Diag(Args[format_idx]->getBeginLoc(),
7356 diag::warn_format_string_type_incompatible)
7357 << PVFormatMatches->getType()->getName()
7359 if (!InFunctionCall) {
7360 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7361 diag::note_format_string_defined);
7363 return SLCT_UncheckedLiteral;
7366 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7367 Args, APK, format_idx, firstDataArg,
Type, CallType,
7368 false, CheckedVarArgs, UncoveredArg,
7369 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7373 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7376 PVFormat->getFirstArg(), &CallerFSI))
7378 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7382 S.
Diag(Args[format_idx]->getBeginLoc(),
7383 diag::warn_format_string_type_incompatible)
7384 << PVFormat->getType()->getName()
7386 if (!InFunctionCall) {
7389 return SLCT_UncheckedLiteral;
7402 return SLCT_UncheckedLiteral;
7410 return SLCT_NotALiteral;
7413 case Stmt::CallExprClass:
7414 case Stmt::CXXMemberCallExprClass: {
7418 StringLiteralCheckType CommonResult;
7419 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7420 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7422 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7423 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7424 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7431 return CommonResult;
7433 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7435 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7436 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7439 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7440 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7441 UncoveredArg, Offset, CallerFormatParamIdx,
7442 IgnoreStringsWithoutSpecifiers);
7448 format_idx, firstDataArg,
Type, CallType,
7449 false, CheckedVarArgs,
7450 UncoveredArg, Offset, CallerFormatParamIdx,
7451 IgnoreStringsWithoutSpecifiers);
7452 return SLCT_NotALiteral;
7454 case Stmt::ObjCMessageExprClass: {
7456 if (
const auto *MD = ME->getMethodDecl()) {
7457 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7466 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7468 MD->getSelector().isKeywordSelector(
7469 {
"localizedStringForKey",
"value",
"table"})) {
7470 IgnoreStringsWithoutSpecifiers =
true;
7473 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7475 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7476 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7477 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7481 return SLCT_NotALiteral;
7483 case Stmt::ObjCStringLiteralClass:
7484 case Stmt::StringLiteralClass: {
7493 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7496 return SLCT_NotALiteral;
7498 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7500 format_idx, firstDataArg,
Type, InFunctionCall,
7501 CallType, CheckedVarArgs, UncoveredArg,
7502 IgnoreStringsWithoutSpecifiers);
7503 return SLCT_CheckedLiteral;
7506 return SLCT_NotALiteral;
7508 case Stmt::BinaryOperatorClass: {
7522 if (LIsInt != RIsInt) {
7526 if (BinOpKind == BO_Add) {
7539 return SLCT_NotALiteral;
7541 case Stmt::UnaryOperatorClass: {
7543 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7544 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7546 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7556 return SLCT_NotALiteral;
7560 return SLCT_NotALiteral;
7571 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7572 if (isa_and_nonnull<StringLiteral>(LVE))
7593 return "freebsd_kprintf";
7602 return llvm::StringSwitch<FormatStringType>(Flavor)
7604 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7609 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7625bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7629 llvm::SmallBitVector &CheckedVarArgs) {
7630 FormatStringInfo FSI;
7634 return CheckFormatArguments(
7635 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7640bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7644 llvm::SmallBitVector &CheckedVarArgs) {
7645 FormatStringInfo FSI;
7649 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7650 Format->getFormatString(), FSI.FormatIdx,
7652 CallType, Loc, Range, CheckedVarArgs);
7660 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7673 unsigned CallerArgumentIndexOffset =
7676 unsigned FirstArgumentIndex = -1;
7686 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7687 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7691 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7692 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7694 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7697 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7698 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7701 FirstArgumentIndex =
7702 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7708 ? (NumCallerParams + CallerArgumentIndexOffset)
7713 if (!ReferenceFormatString)
7719 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7721 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7723 std::string
Attr, Fixit;
7724 llvm::raw_string_ostream AttrOS(
Attr);
7726 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7727 << FirstArgumentIndex <<
")";
7729 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7731 AttrOS.write_escaped(ReferenceFormatString->
getString());
7735 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7746 llvm::raw_string_ostream IS(Fixit);
7754 if (LO.C23 || LO.CPlusPlus11)
7755 IS <<
"[[gnu::" <<
Attr <<
"]]";
7756 else if (LO.ObjC || LO.GNUMode)
7757 IS <<
"__attribute__((" <<
Attr <<
"))";
7771 Caller->
addAttr(FormatAttr::CreateImplicit(
7773 FormatStringIndex, FirstArgumentIndex));
7775 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7777 FormatStringIndex, ReferenceFormatString));
7781 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7793 unsigned format_idx,
unsigned firstDataArg,
7797 llvm::SmallBitVector &CheckedVarArgs) {
7799 if (format_idx >= Args.size()) {
7800 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7804 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7818 UncoveredArgHandler UncoveredArg;
7819 std::optional<unsigned> CallerParamIdx;
7821 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7822 firstDataArg,
Type, CallType,
7823 true, CheckedVarArgs, UncoveredArg,
7824 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7827 if (UncoveredArg.hasUncoveredArg()) {
7828 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7829 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7830 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7833 if (CT != SLCT_NotALiteral)
7835 return CT == SLCT_CheckedLiteral;
7841 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7847 this, Args, APK, ReferenceFormatString, format_idx,
7848 firstDataArg,
Type, *CallerParamIdx, Loc))
7858 if (Args.size() == firstDataArg) {
7859 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7867 Diag(FormatLoc, diag::note_format_security_fixit)
7871 Diag(FormatLoc, diag::note_format_security_fixit)
7876 Diag(FormatLoc, diag::warn_format_nonliteral)
7887 const FormatStringLiteral *FExpr;
7888 const Expr *OrigFormatExpr;
7890 const unsigned FirstDataArg;
7891 const unsigned NumDataArgs;
7894 ArrayRef<const Expr *> Args;
7896 llvm::SmallBitVector CoveredArgs;
7897 bool usesPositionalArgs =
false;
7898 bool atFirstArg =
true;
7899 bool inFunctionCall;
7901 llvm::SmallBitVector &CheckedVarArgs;
7902 UncoveredArgHandler &UncoveredArg;
7905 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
7907 unsigned firstDataArg,
unsigned numDataArgs,
7909 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7911 llvm::SmallBitVector &CheckedVarArgs,
7912 UncoveredArgHandler &UncoveredArg)
7913 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7914 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7915 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7916 inFunctionCall(inFunctionCall), CallType(callType),
7917 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7918 CoveredArgs.resize(numDataArgs);
7919 CoveredArgs.reset();
7922 bool HasFormatArguments()
const {
7927 void DoneProcessing();
7929 void HandleIncompleteSpecifier(
const char *startSpecifier,
7930 unsigned specifierLen)
override;
7932 void HandleInvalidLengthModifier(
7933 const analyze_format_string::FormatSpecifier &FS,
7934 const analyze_format_string::ConversionSpecifier &CS,
7935 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
7937 void HandleNonStandardLengthModifier(
7938 const analyze_format_string::FormatSpecifier &FS,
7939 const char *startSpecifier,
unsigned specifierLen);
7941 void HandleNonStandardConversionSpecifier(
7942 const analyze_format_string::ConversionSpecifier &CS,
7943 const char *startSpecifier,
unsigned specifierLen);
7945 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7947 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
7950 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7952 void HandleNullChar(
const char *nullCharacter)
override;
7954 template <
typename Range>
7956 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7957 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7958 bool IsStringLocation, Range StringRange,
7959 ArrayRef<FixItHint> Fixit = {});
7962 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7963 const char *startSpec,
7964 unsigned specifierLen,
7965 const char *csStart,
unsigned csLen);
7967 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7968 const char *startSpec,
7969 unsigned specifierLen);
7971 SourceRange getFormatStringRange();
7972 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7973 unsigned specifierLen);
7974 SourceLocation getLocationOfByte(
const char *x);
7976 const Expr *getDataArg(
unsigned i)
const;
7978 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7979 const analyze_format_string::ConversionSpecifier &CS,
7980 const char *startSpecifier,
unsigned specifierLen,
7983 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
7984 const Expr *E,
const char *startSpecifier,
7985 unsigned specifierLen);
7987 template <
typename Range>
7988 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7989 bool IsStringLocation, Range StringRange,
7990 ArrayRef<FixItHint> Fixit = {});
7995SourceRange CheckFormatHandler::getFormatStringRange() {
8000CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8001 unsigned specifierLen) {
8003 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8011SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8016void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8017 unsigned specifierLen) {
8018 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8019 getLocationOfByte(startSpecifier),
8021 getSpecifierRange(startSpecifier, specifierLen));
8024bool CheckFormatHandler::CheckUnsupportedType(
8026 const char *StartSpecifier,
unsigned SpecifierLen) {
8030 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8033 getSpecifierRange(StartSpecifier, SpecifierLen));
8037void CheckFormatHandler::HandleInvalidLengthModifier(
8040 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8052 getSpecifierRange(startSpecifier, specifierLen));
8054 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8055 << FixedLM->toString()
8060 if (DiagID == diag::warn_format_nonsensical_length)
8066 getSpecifierRange(startSpecifier, specifierLen), Hint);
8070void CheckFormatHandler::HandleNonStandardLengthModifier(
8072 const char *startSpecifier,
unsigned specifierLen) {
8081 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8085 getSpecifierRange(startSpecifier, specifierLen));
8087 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8088 << FixedLM->toString()
8092 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8096 getSpecifierRange(startSpecifier, specifierLen));
8100void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8102 const char *startSpecifier,
unsigned specifierLen) {
8108 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8112 getSpecifierRange(startSpecifier, specifierLen));
8115 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8116 << FixedCS->toString()
8119 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8123 getSpecifierRange(startSpecifier, specifierLen));
8127void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8129 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8130 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8131 getLocationOfByte(startPos),
8133 getSpecifierRange(startPos, posLen));
8136void CheckFormatHandler::HandleInvalidPosition(
8137 const char *startSpecifier,
unsigned specifierLen,
8140 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8141 EmitFormatDiagnostic(
8142 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8143 getLocationOfByte(startSpecifier),
true,
8144 getSpecifierRange(startSpecifier, specifierLen));
8147void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8151 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8152 getLocationOfByte(startPos),
8154 getSpecifierRange(startPos, posLen));
8157void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8160 EmitFormatDiagnostic(
8161 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8162 getLocationOfByte(nullCharacter),
true,
8163 getFormatStringRange());
8169const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8170 return Args[FirstDataArg + i];
8173void CheckFormatHandler::DoneProcessing() {
8176 if (HasFormatArguments()) {
8179 signed notCoveredArg = CoveredArgs.find_first();
8180 if (notCoveredArg >= 0) {
8181 assert((
unsigned)notCoveredArg < NumDataArgs);
8182 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8184 UncoveredArg.setAllCovered();
8189void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8190 const Expr *ArgExpr) {
8191 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8202 for (
auto E : DiagnosticExprs)
8205 CheckFormatHandler::EmitFormatDiagnostic(
8206 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8210bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8212 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8213 bool keepGoing =
true;
8214 if (argIndex < NumDataArgs) {
8217 CoveredArgs.set(argIndex);
8232 std::string CodePointStr;
8233 if (!llvm::sys::locale::isPrint(*csStart)) {
8234 llvm::UTF32 CodePoint;
8235 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8236 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8237 llvm::ConversionResult
Result =
8238 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8240 if (
Result != llvm::conversionOK) {
8241 unsigned char FirstChar = *csStart;
8242 CodePoint = (llvm::UTF32)FirstChar;
8245 llvm::raw_string_ostream
OS(CodePointStr);
8246 if (CodePoint < 256)
8247 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8248 else if (CodePoint <= 0xFFFF)
8249 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8251 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8255 EmitFormatDiagnostic(
8256 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8257 true, getSpecifierRange(startSpec, specifierLen));
8262void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8263 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8264 EmitFormatDiagnostic(
8265 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8266 true, getSpecifierRange(startSpec, specifierLen));
8269bool CheckFormatHandler::CheckNumArgs(
8272 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8274 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8277 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8278 << (argIndex + 1) << NumDataArgs)
8279 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8280 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8282 getSpecifierRange(startSpecifier, specifierLen));
8286 UncoveredArg.setAllCovered();
8292template <
typename Range>
8295 bool IsStringLocation,
8298 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8299 IsStringLocation, StringRange, FixIt);
8329template <
typename Range>
8330void CheckFormatHandler::EmitFormatDiagnostic(
8331 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8334 if (InFunctionCall) {
8339 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8343 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8344 diag::note_format_string_defined);
8346 Note << StringRange;
8355class CheckPrintfHandler :
public CheckFormatHandler {
8357 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8359 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8361 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8363 llvm::SmallBitVector &CheckedVarArgs,
8364 UncoveredArgHandler &UncoveredArg)
8365 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8366 numDataArgs, beg, APK, Args, formatIdx,
8367 inFunctionCall, CallType, CheckedVarArgs,
8370 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8373 bool allowsObjCArg()
const {
8374 return FSType == FormatStringType::NSString ||
8375 FSType == FormatStringType::OSLog ||
8376 FSType == FormatStringType::OSTrace;
8379 bool HandleInvalidPrintfConversionSpecifier(
8380 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8381 unsigned specifierLen)
override;
8383 void handleInvalidMaskType(StringRef MaskType)
override;
8385 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8386 const char *startSpecifier,
unsigned specifierLen,
8387 const TargetInfo &
Target)
override;
8388 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8389 const char *StartSpecifier,
unsigned SpecifierLen,
8392 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8393 unsigned k,
const char *startSpecifier,
8394 unsigned specifierLen);
8395 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8396 const analyze_printf::OptionalAmount &Amt,
8397 unsigned type,
const char *startSpecifier,
8398 unsigned specifierLen);
8399 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8400 const analyze_printf::OptionalFlag &flag,
8401 const char *startSpecifier,
unsigned specifierLen);
8402 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8403 const analyze_printf::OptionalFlag &ignoredFlag,
8404 const analyze_printf::OptionalFlag &flag,
8405 const char *startSpecifier,
unsigned specifierLen);
8406 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8408 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8409 unsigned flagLen)
override;
8411 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8412 unsigned flagLen)
override;
8415 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8416 const char *flagsEnd,
8417 const char *conversionPosition)
override;
8422class EquatableFormatArgument {
8424 enum SpecifierSensitivity :
unsigned {
8431 enum FormatArgumentRole :
unsigned {
8439 analyze_format_string::ArgType ArgType;
8440 analyze_format_string::LengthModifier LengthMod;
8441 StringRef SpecifierLetter;
8442 CharSourceRange
Range;
8443 SourceLocation ElementLoc;
8444 FormatArgumentRole
Role : 2;
8445 SpecifierSensitivity Sensitivity : 2;
8446 unsigned Position : 14;
8447 unsigned ModifierFor : 14;
8449 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8450 bool InFunctionCall)
const;
8453 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8454 analyze_format_string::LengthModifier LengthMod,
8455 StringRef SpecifierLetter,
8456 analyze_format_string::ArgType ArgType,
8457 FormatArgumentRole
Role,
8458 SpecifierSensitivity Sensitivity,
unsigned Position,
8459 unsigned ModifierFor)
8460 : ArgType(ArgType), LengthMod(LengthMod),
8461 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8462 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8463 ModifierFor(ModifierFor) {}
8465 unsigned getPosition()
const {
return Position; }
8466 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8468 analyze_format_string::LengthModifier getLengthModifier()
const {
8471 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8473 std::string buildFormatSpecifier()
const {
8475 llvm::raw_string_ostream(result)
8476 << getLengthModifier().
toString() << SpecifierLetter;
8480 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8481 const Expr *FmtExpr,
bool InFunctionCall)
const;
8485class DecomposePrintfHandler :
public CheckPrintfHandler {
8486 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8489 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8490 const Expr *origFormatExpr,
8492 unsigned numDataArgs,
bool isObjC,
const char *beg,
8494 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8496 llvm::SmallBitVector &CheckedVarArgs,
8497 UncoveredArgHandler &UncoveredArg,
8498 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8499 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8500 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8501 inFunctionCall, CallType, CheckedVarArgs,
8503 Specs(Specs), HadError(
false) {}
8507 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8509 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8511 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8512 const char *startSpecifier,
8513 unsigned specifierLen,
8514 const TargetInfo &
Target)
override;
8519bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8521 unsigned specifierLen) {
8525 return HandleInvalidConversionSpecifier(
8530void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8531 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8539 return T->isRecordType() || T->isComplexType();
8542bool CheckPrintfHandler::HandleAmount(
8544 const char *startSpecifier,
unsigned specifierLen) {
8546 if (HasFormatArguments()) {
8548 if (argIndex >= NumDataArgs) {
8549 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8553 getSpecifierRange(startSpecifier, specifierLen));
8563 CoveredArgs.set(argIndex);
8564 const Expr *Arg = getDataArg(argIndex);
8575 ? diag::err_printf_asterisk_wrong_type
8576 : diag::warn_printf_asterisk_wrong_type;
8577 EmitFormatDiagnostic(S.
PDiag(DiagID)
8582 getSpecifierRange(startSpecifier, specifierLen));
8592void CheckPrintfHandler::HandleInvalidAmount(
8595 const char *startSpecifier,
unsigned specifierLen) {
8605 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8609 getSpecifierRange(startSpecifier, specifierLen), fixit);
8614 const char *startSpecifier,
8615 unsigned specifierLen) {
8619 EmitFormatDiagnostic(
8620 S.
PDiag(diag::warn_printf_nonsensical_flag)
8624 getSpecifierRange(startSpecifier, specifierLen),
8628void CheckPrintfHandler::HandleIgnoredFlag(
8632 unsigned specifierLen) {
8634 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8638 getSpecifierRange(startSpecifier, specifierLen),
8640 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8643void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8646 EmitFormatDiagnostic(
8647 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8648 true, getSpecifierRange(startFlag, flagLen));
8651void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8654 auto Range = getSpecifierRange(startFlag, flagLen);
8655 StringRef flag(startFlag, flagLen);
8656 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8657 getLocationOfByte(startFlag),
8662void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8663 const char *flagsStart,
const char *flagsEnd,
8664 const char *conversionPosition) {
8666 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8667 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8668 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8669 getLocationOfByte(conversionPosition),
8675 const Expr *FmtExpr,
8676 bool InFunctionCall)
const {
8677 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8678 ElementLoc,
true, Range);
8681bool EquatableFormatArgument::VerifyCompatible(
8682 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8683 bool InFunctionCall)
const {
8688 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8689 FmtExpr, InFunctionCall);
8690 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8694 if (
Role != FAR_Data) {
8695 if (ModifierFor !=
Other.ModifierFor) {
8698 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8699 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8700 FmtExpr, InFunctionCall);
8701 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8707 bool HadError =
false;
8708 if (Sensitivity !=
Other.Sensitivity) {
8711 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8712 << Sensitivity <<
Other.Sensitivity,
8713 FmtExpr, InFunctionCall);
8714 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8715 << 0 <<
Other.Range;
8718 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8722 case MK::MatchPromotion:
8726 case MK::NoMatchTypeConfusion:
8727 case MK::NoMatchPromotionTypeConfusion:
8729 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8730 << buildFormatSpecifier()
8731 <<
Other.buildFormatSpecifier(),
8732 FmtExpr, InFunctionCall);
8733 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8734 << 0 <<
Other.Range;
8737 case MK::NoMatchPedantic:
8739 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8740 << buildFormatSpecifier()
8741 <<
Other.buildFormatSpecifier(),
8742 FmtExpr, InFunctionCall);
8743 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8744 << 0 <<
Other.Range;
8747 case MK::NoMatchSignedness:
8749 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8750 << buildFormatSpecifier()
8751 <<
Other.buildFormatSpecifier(),
8752 FmtExpr, InFunctionCall);
8753 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8754 << 0 <<
Other.Range;
8760bool DecomposePrintfHandler::GetSpecifiers(
8761 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8764 StringRef
Data = FSL->getString();
8765 const char *Str =
Data.data();
8766 llvm::SmallBitVector BV;
8767 UncoveredArgHandler UA;
8768 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8769 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8781 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8782 const EquatableFormatArgument &B) {
8783 return A.getPosition() < B.getPosition();
8788bool DecomposePrintfHandler::HandlePrintfSpecifier(
8791 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8806 const unsigned Unset = ~0;
8807 unsigned FieldWidthIndex = Unset;
8808 unsigned PrecisionIndex = Unset;
8812 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8813 FieldWidthIndex = Specs.size();
8815 getSpecifierRange(startSpecifier, specifierLen),
8816 getLocationOfByte(FieldWidth.getStart()),
8818 FieldWidth.getArgType(S.
Context),
8819 EquatableFormatArgument::FAR_FieldWidth,
8820 EquatableFormatArgument::SS_None,
8821 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
8827 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8828 PrecisionIndex = Specs.size();
8830 getSpecifierRange(startSpecifier, specifierLen),
8831 getLocationOfByte(Precision.getStart()),
8833 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8834 EquatableFormatArgument::SS_None,
8835 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8841 unsigned SpecIndex =
8843 if (FieldWidthIndex != Unset)
8844 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8845 if (PrecisionIndex != Unset)
8846 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8848 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8850 Sensitivity = EquatableFormatArgument::SS_Private;
8852 Sensitivity = EquatableFormatArgument::SS_Public;
8854 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8856 Sensitivity = EquatableFormatArgument::SS_None;
8859 getSpecifierRange(startSpecifier, specifierLen),
8862 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8867 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8872 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8873 SpecIndex + 1, SpecIndex);
8881template<
typename MemberKind>
8892 R.suppressDiagnostics();
8899 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8914 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8916 if ((*MI)->getMinRequiredArguments() == 0)
8924bool CheckPrintfHandler::checkForCStrMembers(
8931 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8934 if (
Method->getMinRequiredArguments() == 0 &&
8947bool CheckPrintfHandler::HandlePrintfSpecifier(
8960 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8961 startSpecifier, specifierLen);
8973 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
8978 if (!CS.consumesDataArgument()) {
8986 if (argIndex < NumDataArgs) {
8990 CoveredArgs.set(argIndex);
8997 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9000 if (HasFormatArguments()) {
9002 CoveredArgs.set(argIndex + 1);
9005 const Expr *Ex = getDataArg(argIndex);
9009 : ArgType::CPointerTy;
9011 EmitFormatDiagnostic(
9012 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9016 getSpecifierRange(startSpecifier, specifierLen));
9019 Ex = getDataArg(argIndex + 1);
9022 EmitFormatDiagnostic(
9023 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9027 getSpecifierRange(startSpecifier, specifierLen));
9034 if (!allowsObjCArg() && CS.isObjCArg()) {
9035 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9042 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9049 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9050 getLocationOfByte(CS.getStart()),
9052 getSpecifierRange(startSpecifier, specifierLen));
9062 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9069 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9073 getSpecifierRange(startSpecifier, specifierLen));
9076 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9080 getSpecifierRange(startSpecifier, specifierLen));
9084 const llvm::Triple &Triple =
Target.getTriple();
9086 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9087 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9088 getLocationOfByte(CS.getStart()),
9090 getSpecifierRange(startSpecifier, specifierLen));
9096 startSpecifier, specifierLen);
9102 startSpecifier, specifierLen);
9108 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9109 getLocationOfByte(startSpecifier),
9111 getSpecifierRange(startSpecifier, specifierLen));
9120 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9122 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9131 startSpecifier, specifierLen);
9134 startSpecifier, specifierLen);
9139 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9140 diag::warn_format_nonsensical_length);
9142 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9144 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9145 diag::warn_format_non_standard_conversion_spec);
9148 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9151 if (!HasFormatArguments())
9154 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9157 const Expr *Arg = getDataArg(argIndex);
9161 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9173 case Stmt::ArraySubscriptExprClass:
9174 case Stmt::CallExprClass:
9175 case Stmt::CharacterLiteralClass:
9176 case Stmt::CXXBoolLiteralExprClass:
9177 case Stmt::DeclRefExprClass:
9178 case Stmt::FloatingLiteralClass:
9179 case Stmt::IntegerLiteralClass:
9180 case Stmt::MemberExprClass:
9181 case Stmt::ObjCArrayLiteralClass:
9182 case Stmt::ObjCBoolLiteralExprClass:
9183 case Stmt::ObjCBoxedExprClass:
9184 case Stmt::ObjCDictionaryLiteralClass:
9185 case Stmt::ObjCEncodeExprClass:
9186 case Stmt::ObjCIvarRefExprClass:
9187 case Stmt::ObjCMessageExprClass:
9188 case Stmt::ObjCPropertyRefExprClass:
9189 case Stmt::ObjCStringLiteralClass:
9190 case Stmt::ObjCSubscriptRefExprClass:
9191 case Stmt::ParenExprClass:
9192 case Stmt::StringLiteralClass:
9193 case Stmt::UnaryOperatorClass:
9200static std::pair<QualType, StringRef>
9206 StringRef Name = UserTy->getDecl()->getName();
9207 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9208 .Case(
"CFIndex", Context.getNSIntegerType())
9209 .Case(
"NSInteger", Context.getNSIntegerType())
9210 .Case(
"NSUInteger", Context.getNSUIntegerType())
9211 .Case(
"SInt32", Context.IntTy)
9212 .Case(
"UInt32", Context.UnsignedIntTy)
9216 return std::make_pair(CastTy, Name);
9218 TyTy = UserTy->desugar();
9222 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9232 StringRef TrueName, FalseName;
9235 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9237 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9239 if (TrueTy == FalseTy)
9240 return std::make_pair(TrueTy, TrueName);
9241 else if (TrueTy.
isNull())
9242 return std::make_pair(FalseTy, FalseName);
9243 else if (FalseTy.
isNull())
9244 return std::make_pair(TrueTy, TrueName);
9247 return std::make_pair(
QualType(), StringRef());
9266 From = VecTy->getElementType();
9268 To = VecTy->getElementType();
9279 diag::warn_format_conversion_argument_type_mismatch_signedness,
9283 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9290bool CheckPrintfHandler::checkFormatExpr(
9292 unsigned SpecifierLen,
const Expr *E) {
9303 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9304 ExprTy = TET->getUnderlyingExpr()->getType();
9307 if (
const OverflowBehaviorType *OBT =
9309 ExprTy = OBT->getUnderlyingType();
9323 getSpecifierRange(StartSpecifier, SpecifierLen);
9325 llvm::raw_svector_ostream os(FSString);
9327 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9338 getSpecifierRange(StartSpecifier, SpecifierLen);
9339 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9344 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9352 if (
Match == ArgType::Match)
9356 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9365 E = ICE->getSubExpr();
9375 if (OrigMatch == ArgType::NoMatchSignedness &&
9376 ImplicitMatch != ArgType::NoMatchSignedness)
9383 if (ImplicitMatch == ArgType::Match)
9401 if (
Match == ArgType::MatchPromotion)
9405 if (
Match == ArgType::MatchPromotion) {
9409 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9410 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9414 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9415 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9416 Match = ImplicitMatch;
9417 assert(
Match != ArgType::MatchPromotion);
9420 bool IsEnum =
false;
9421 bool IsScopedEnum =
false;
9424 IntendedTy = ED->getIntegerType();
9425 if (!ED->isScoped()) {
9426 ExprTy = IntendedTy;
9431 IsScopedEnum =
true;
9438 if (isObjCContext() &&
9449 const llvm::APInt &
V = IL->getValue();
9459 if (TD->getUnderlyingType() == IntendedTy)
9469 bool ShouldNotPrintDirectly =
false;
9470 StringRef CastTyName;
9473 std::tie(CastTy, CastTyName) =
9479 if (!IsScopedEnum &&
9480 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9484 IntendedTy = CastTy;
9485 ShouldNotPrintDirectly =
true;
9490 PrintfSpecifier fixedFS = FS;
9497 llvm::raw_svector_ostream os(buf);
9500 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9502 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9508 llvm_unreachable(
"expected non-matching");
9510 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9513 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9516 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9519 Diag = diag::warn_format_conversion_argument_type_mismatch;
9540 llvm::raw_svector_ostream CastFix(CastBuf);
9541 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9543 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9549 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9554 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9576 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9582 Name = TypedefTy->getDecl()->getName();
9586 ? diag::warn_format_argument_needs_cast_pedantic
9587 : diag::warn_format_argument_needs_cast;
9588 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9599 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9600 : diag::warn_format_conversion_argument_type_mismatch;
9602 EmitFormatDiagnostic(
9610 getSpecifierRange(StartSpecifier, SpecifierLen);
9614 bool EmitTypeMismatch =
false;
9618 bool EmitOSLogError =
false;
9627 llvm_unreachable(
"expected non-matching");
9629 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9632 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9635 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9639 Diag = diag::warn_format_conversion_argument_type_mismatch;
9643 if (!EmitOSLogError)
9644 EmitFormatDiagnostic(
9653 EmitTypeMismatch =
true;
9657 EmitOSLogError =
true;
9659 EmitFormatDiagnostic(
9660 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9661 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9665 checkForCStrMembers(AT, E);
9671 EmitTypeMismatch =
true;
9673 EmitFormatDiagnostic(
9674 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9675 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9689 EmitFormatDiagnostic(
9690 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
9695 if (EmitTypeMismatch) {
9701 EmitFormatDiagnostic(
9702 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9708 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9709 "format string specifier index out of range");
9710 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9720class CheckScanfHandler :
public CheckFormatHandler {
9722 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
9724 unsigned firstDataArg,
unsigned numDataArgs,
9726 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9728 llvm::SmallBitVector &CheckedVarArgs,
9729 UncoveredArgHandler &UncoveredArg)
9730 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
9731 numDataArgs, beg, APK, Args, formatIdx,
9732 inFunctionCall, CallType, CheckedVarArgs,
9735 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9736 const char *startSpecifier,
9737 unsigned specifierLen)
override;
9740 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9741 const char *startSpecifier,
9742 unsigned specifierLen)
override;
9744 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9749void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9751 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9752 getLocationOfByte(end),
true,
9753 getSpecifierRange(start, end - start));
9756bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9758 unsigned specifierLen) {
9762 return HandleInvalidConversionSpecifier(
9767bool CheckScanfHandler::HandleScanfSpecifier(
9769 unsigned specifierLen) {
9782 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9783 startSpecifier, specifierLen);
9794 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9809 if (argIndex < NumDataArgs) {
9813 CoveredArgs.set(argIndex);
9819 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9820 diag::warn_format_nonsensical_length);
9822 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9824 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9825 diag::warn_format_non_standard_conversion_spec);
9828 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9831 if (!HasFormatArguments())
9834 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9838 const Expr *Ex = getDataArg(argIndex);
9848 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
9859 ScanfSpecifier fixedFS = FS;
9864 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9866 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9867 : diag::warn_format_conversion_argument_type_mismatch;
9872 llvm::raw_svector_ostream os(buf);
9875 EmitFormatDiagnostic(
9880 getSpecifierRange(startSpecifier, specifierLen),
9882 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9889 getSpecifierRange(startSpecifier, specifierLen));
9899 const Expr *FmtExpr,
bool InFunctionCall) {
9900 bool HadError =
false;
9901 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9902 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9903 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9915 for (; FmtIter < FmtEnd; ++FmtIter) {
9919 if (FmtIter->getPosition() < RefIter->getPosition())
9923 if (FmtIter->getPosition() > RefIter->getPosition())
9927 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9931 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9932 return Arg.getPosition() != RefIter->getPosition();
9936 if (FmtIter < FmtEnd) {
9937 CheckFormatHandler::EmitFormatDiagnostic(
9938 S, InFunctionCall, FmtExpr,
9939 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9940 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9941 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9942 }
else if (RefIter < RefEnd) {
9943 CheckFormatHandler::EmitFormatDiagnostic(
9944 S, InFunctionCall, FmtExpr,
9945 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9948 << 1 << RefIter->getSourceRange();
9954 Sema &S,
const FormatStringLiteral *FExpr,
9959 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9960 bool IgnoreStringsWithoutSpecifiers) {
9962 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9963 CheckFormatHandler::EmitFormatDiagnostic(
9964 S, inFunctionCall, Args[format_idx],
9965 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9971 StringRef StrRef = FExpr->getString();
9972 const char *Str = StrRef.data();
9976 assert(T &&
"String literal not of constant array type!");
9977 size_t TypeSize = T->getZExtSize();
9978 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9979 const unsigned numDataArgs = Args.size() - firstDataArg;
9981 if (IgnoreStringsWithoutSpecifiers &&
9988 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9989 CheckFormatHandler::EmitFormatDiagnostic(
9990 S, inFunctionCall, Args[format_idx],
9991 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9992 FExpr->getBeginLoc(),
9998 if (StrLen == 0 && numDataArgs > 0) {
9999 CheckFormatHandler::EmitFormatDiagnostic(
10000 S, inFunctionCall, Args[format_idx],
10001 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10012 if (ReferenceFormatString ==
nullptr) {
10013 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10014 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10015 inFunctionCall, CallType, CheckedVarArgs,
10022 H.DoneProcessing();
10025 Type, ReferenceFormatString, FExpr->getFormatString(),
10026 inFunctionCall ?
nullptr : Args[format_idx]);
10029 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10030 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10031 CallType, CheckedVarArgs, UncoveredArg);
10035 H.DoneProcessing();
10051 FormatStringLiteral RefLit = AuthoritativeFormatString;
10052 FormatStringLiteral TestLit = TestedFormatString;
10054 bool DiagAtStringLiteral;
10055 if (FunctionCallArg) {
10056 Arg = FunctionCallArg;
10057 DiagAtStringLiteral =
false;
10059 Arg = TestedFormatString;
10060 DiagAtStringLiteral =
true;
10062 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10063 AuthoritativeFormatString,
Type,
10064 IsObjC,
true, RefArgs) &&
10065 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10066 DiagAtStringLiteral, FmtArgs)) {
10068 TestedFormatString, FmtArgs, Arg,
10069 DiagAtStringLiteral);
10082 FormatStringLiteral RefLit = Str;
10086 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10095 bool HadError =
false;
10096 auto Iter = Args.begin();
10097 auto End = Args.end();
10098 while (Iter != End) {
10099 const auto &FirstInGroup = *Iter;
10101 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10103 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10112 const char *Str = StrRef.data();
10115 assert(T &&
"String literal not of constant array type!");
10116 size_t TypeSize = T->getZExtSize();
10117 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10127 switch (AbsFunction) {
10131 case Builtin::BI__builtin_abs:
10132 return Builtin::BI__builtin_labs;
10133 case Builtin::BI__builtin_labs:
10134 return Builtin::BI__builtin_llabs;
10135 case Builtin::BI__builtin_llabs:
10138 case Builtin::BI__builtin_fabsf:
10139 return Builtin::BI__builtin_fabs;
10140 case Builtin::BI__builtin_fabs:
10141 return Builtin::BI__builtin_fabsl;
10142 case Builtin::BI__builtin_fabsl:
10145 case Builtin::BI__builtin_cabsf:
10146 return Builtin::BI__builtin_cabs;
10147 case Builtin::BI__builtin_cabs:
10148 return Builtin::BI__builtin_cabsl;
10149 case Builtin::BI__builtin_cabsl:
10152 case Builtin::BIabs:
10153 return Builtin::BIlabs;
10154 case Builtin::BIlabs:
10155 return Builtin::BIllabs;
10156 case Builtin::BIllabs:
10159 case Builtin::BIfabsf:
10160 return Builtin::BIfabs;
10161 case Builtin::BIfabs:
10162 return Builtin::BIfabsl;
10163 case Builtin::BIfabsl:
10166 case Builtin::BIcabsf:
10167 return Builtin::BIcabs;
10168 case Builtin::BIcabs:
10169 return Builtin::BIcabsl;
10170 case Builtin::BIcabsl:
10177 unsigned AbsType) {
10199 unsigned AbsFunctionKind) {
10200 unsigned BestKind = 0;
10201 uint64_t ArgSize = Context.getTypeSize(ArgType);
10202 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10205 if (Context.getTypeSize(ParamType) >= ArgSize) {
10208 else if (Context.hasSameType(ParamType, ArgType)) {
10224 if (T->isIntegralOrEnumerationType())
10226 if (T->isRealFloatingType())
10228 if (T->isAnyComplexType())
10231 llvm_unreachable(
"Type not integer, floating, or complex");
10238 switch (ValueKind) {
10243 case Builtin::BI__builtin_fabsf:
10244 case Builtin::BI__builtin_fabs:
10245 case Builtin::BI__builtin_fabsl:
10246 case Builtin::BI__builtin_cabsf:
10247 case Builtin::BI__builtin_cabs:
10248 case Builtin::BI__builtin_cabsl:
10249 return Builtin::BI__builtin_abs;
10250 case Builtin::BIfabsf:
10251 case Builtin::BIfabs:
10252 case Builtin::BIfabsl:
10253 case Builtin::BIcabsf:
10254 case Builtin::BIcabs:
10255 case Builtin::BIcabsl:
10256 return Builtin::BIabs;
10262 case Builtin::BI__builtin_abs:
10263 case Builtin::BI__builtin_labs:
10264 case Builtin::BI__builtin_llabs:
10265 case Builtin::BI__builtin_cabsf:
10266 case Builtin::BI__builtin_cabs:
10267 case Builtin::BI__builtin_cabsl:
10268 return Builtin::BI__builtin_fabsf;
10269 case Builtin::BIabs:
10270 case Builtin::BIlabs:
10271 case Builtin::BIllabs:
10272 case Builtin::BIcabsf:
10273 case Builtin::BIcabs:
10274 case Builtin::BIcabsl:
10275 return Builtin::BIfabsf;
10281 case Builtin::BI__builtin_abs:
10282 case Builtin::BI__builtin_labs:
10283 case Builtin::BI__builtin_llabs:
10284 case Builtin::BI__builtin_fabsf:
10285 case Builtin::BI__builtin_fabs:
10286 case Builtin::BI__builtin_fabsl:
10287 return Builtin::BI__builtin_cabsf;
10288 case Builtin::BIabs:
10289 case Builtin::BIlabs:
10290 case Builtin::BIllabs:
10291 case Builtin::BIfabsf:
10292 case Builtin::BIfabs:
10293 case Builtin::BIfabsl:
10294 return Builtin::BIcabsf;
10297 llvm_unreachable(
"Unable to convert function");
10308 case Builtin::BI__builtin_abs:
10309 case Builtin::BI__builtin_fabs:
10310 case Builtin::BI__builtin_fabsf:
10311 case Builtin::BI__builtin_fabsl:
10312 case Builtin::BI__builtin_labs:
10313 case Builtin::BI__builtin_llabs:
10314 case Builtin::BI__builtin_cabs:
10315 case Builtin::BI__builtin_cabsf:
10316 case Builtin::BI__builtin_cabsl:
10317 case Builtin::BIabs:
10318 case Builtin::BIlabs:
10319 case Builtin::BIllabs:
10320 case Builtin::BIfabs:
10321 case Builtin::BIfabsf:
10322 case Builtin::BIfabsl:
10323 case Builtin::BIcabs:
10324 case Builtin::BIcabsf:
10325 case Builtin::BIcabsl:
10328 llvm_unreachable(
"Unknown Builtin type");
10334 unsigned AbsKind,
QualType ArgType) {
10335 bool EmitHeaderHint =
true;
10336 const char *HeaderName =
nullptr;
10337 std::string FunctionName;
10338 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10339 FunctionName =
"std::abs";
10340 if (ArgType->isIntegralOrEnumerationType()) {
10341 HeaderName =
"cstdlib";
10342 }
else if (ArgType->isRealFloatingType()) {
10343 HeaderName =
"cmath";
10345 llvm_unreachable(
"Invalid Type");
10351 R.suppressDiagnostics();
10354 for (
const auto *I : R) {
10357 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10359 FDecl = dyn_cast<FunctionDecl>(I);
10374 EmitHeaderHint =
false;
10386 R.suppressDiagnostics();
10389 if (R.isSingleResult()) {
10390 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10392 EmitHeaderHint =
false;
10396 }
else if (!R.empty()) {
10402 S.
Diag(Loc, diag::note_replace_abs_function)
10408 if (!EmitHeaderHint)
10411 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10415template <std::
size_t StrLen>
10417 const char (&Str)[StrLen]) {
10430 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10431 return llvm::is_contained(names, calleeName);
10436 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10437 "__builtin_nanf16",
"__builtin_nanf128"});
10439 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10440 "__builtin_inff16",
"__builtin_inff128"});
10442 llvm_unreachable(
"unknown MathCheck");
10446 if (FDecl->
getName() !=
"infinity")
10449 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10451 if (RDecl->
getName() !=
"numeric_limits")
10468 if (FPO.getNoHonorNaNs() &&
10471 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10472 << 1 << 0 <<
Call->getSourceRange();
10476 if (FPO.getNoHonorInfs() &&
10480 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10481 << 0 << 0 <<
Call->getSourceRange();
10485void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10487 if (
Call->getNumArgs() != 1)
10492 if (AbsKind == 0 && !IsStdAbs)
10495 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10496 QualType ParamType =
Call->getArg(0)->getType();
10501 std::string FunctionName =
10502 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10503 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10504 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10533 if (ArgValueKind == ParamValueKind) {
10534 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10538 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10539 << FDecl << ArgType << ParamType;
10541 if (NewAbsKind == 0)
10545 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10554 if (NewAbsKind == 0)
10557 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10558 << FDecl << ParamValueKind << ArgValueKind;
10561 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10567 if (!
Call || !FDecl)
return;
10571 if (
Call->getExprLoc().isMacroID())
return;
10574 if (
Call->getNumArgs() != 2)
return;
10577 if (!ArgList)
return;
10578 if (ArgList->size() != 1)
return;
10581 const auto& TA = ArgList->
get(0);
10583 QualType ArgType = TA.getAsType();
10587 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10588 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10589 if (!MTE)
return false;
10590 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10591 if (!
Num)
return false;
10592 if (
Num->getValue() != 0)
return false;
10596 const Expr *FirstArg =
Call->getArg(0);
10597 const Expr *SecondArg =
Call->getArg(1);
10598 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10599 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10602 if (IsFirstArgZero == IsSecondArgZero)
return;
10607 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10609 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10610 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10613 SourceRange RemovalRange;
10614 if (IsFirstArgZero) {
10615 RemovalRange = SourceRange(FirstRange.
getBegin(),
10622 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10637 const auto *Size = dyn_cast<BinaryOperator>(E);
10642 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10646 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10647 << SizeRange << FnName;
10648 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10653 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10664 bool &IsContained) {
10667 IsContained =
false;
10680 for (
auto *FD : RD->
fields()) {
10684 IsContained =
true;
10685 return ContainedRD;
10693 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10694 if (Unary->getKind() == UETT_SizeOf)
10703 if (!
SizeOf->isArgumentType())
10704 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10711 return SizeOf->getTypeOfArgument();
10717struct SearchNonTrivialToInitializeField
10720 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10722 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10725 SourceLocation SL) {
10726 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10727 asDerived().visitArray(PDIK, AT, SL);
10731 Super::visitWithKind(PDIK, FT, SL);
10734 void visitARCStrong(QualType FT, SourceLocation SL) {
10737 void visitARCWeak(QualType FT, SourceLocation SL) {
10740 void visitStruct(QualType FT, SourceLocation SL) {
10745 const ArrayType *AT, SourceLocation SL) {
10746 visit(getContext().getBaseElementType(AT), SL);
10748 void visitTrivial(QualType FT, SourceLocation SL) {}
10750 static void diag(QualType RT,
const Expr *E, Sema &S) {
10751 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10760struct SearchNonTrivialToCopyField
10762 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10764 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10767 SourceLocation SL) {
10768 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10769 asDerived().visitArray(PCK, AT, SL);
10773 Super::visitWithKind(PCK, FT, SL);
10776 void visitARCStrong(QualType FT, SourceLocation SL) {
10779 void visitARCWeak(QualType FT, SourceLocation SL) {
10782 void visitPtrAuth(QualType FT, SourceLocation SL) {
10785 void visitStruct(QualType FT, SourceLocation SL) {
10790 SourceLocation SL) {
10791 visit(getContext().getBaseElementType(AT), SL);
10794 SourceLocation SL) {}
10795 void visitTrivial(QualType FT, SourceLocation SL) {}
10796 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10798 static void diag(QualType RT,
const Expr *E, Sema &S) {
10799 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10814 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10815 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10839 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10841 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10842 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10848 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10851 const Expr *SizeArg =
10852 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10854 auto isLiteralZero = [](
const Expr *E) {
10864 if (isLiteralZero(SizeArg) &&
10871 if (BId == Builtin::BIbzero ||
10874 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10875 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10876 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10877 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10878 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10886 if (BId == Builtin::BImemset &&
10890 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10891 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10896void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10903 unsigned ExpectedNumArgs =
10904 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10905 if (
Call->getNumArgs() < ExpectedNumArgs)
10908 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10909 BId == Builtin::BIstrndup ? 1 : 2);
10911 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10915 Call->getBeginLoc(),
Call->getRParenLoc()))
10927 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10928 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10931 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10935 QualType DestTy = Dest->
getType();
10936 QualType PointeeTy;
10937 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10949 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
10955 if (SizeOfArgTy != QualType()) {
10957 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10959 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10960 << FnName << SizeOfArgTy << ArgIdx
10967 PointeeTy = DestTy;
10970 if (PointeeTy == QualType())
10975 if (
const CXXRecordDecl *ContainedRD =
10978 unsigned OperationType = 0;
10979 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10982 if (ArgIdx != 0 || IsCmp) {
10983 if (BId == Builtin::BImemcpy)
10985 else if(BId == Builtin::BImemmove)
10992 PDiag(diag::warn_dyn_class_memaccess)
10993 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10994 << IsContained << ContainedRD << OperationType
10995 <<
Call->getCallee()->getSourceRange());
10997 BId != Builtin::BImemset)
11000 PDiag(diag::warn_arc_object_memaccess)
11001 << ArgIdx << FnName << PointeeTy
11002 <<
Call->getCallee()->getSourceRange());
11009 bool NonTriviallyCopyableCXXRecord =
11013 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11016 PDiag(diag::warn_cstruct_memaccess)
11017 << ArgIdx << FnName << PointeeTy << 0);
11018 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11019 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11020 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11024 PDiag(diag::warn_cxxstruct_memaccess)
11025 << FnName << PointeeTy);
11026 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11029 PDiag(diag::warn_cstruct_memaccess)
11030 << ArgIdx << FnName << PointeeTy << 1);
11031 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11032 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11033 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11037 PDiag(diag::warn_cxxstruct_memaccess)
11038 << FnName << PointeeTy);
11047 PDiag(diag::note_bad_memaccess_silence)
11053bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11055 llvm::FoldingSetNodeID SizeOfArgID;
11061 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11064 QualType DestTy = Dest->
getType();
11065 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11071 if (SizeOfArgID == llvm::FoldingSetNodeID())
11074 llvm::FoldingSetNodeID DestID;
11076 if (DestID == SizeOfArgID) {
11079 unsigned ActionIdx = 0;
11080 StringRef ReadableName = FnName->
getName();
11082 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11083 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11092 SourceLocation SL = SizeOfArg->
getExprLoc();
11097 if (
SM.isMacroArgExpansion(SL)) {
11099 SL =
SM.getSpellingLoc(SL);
11100 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
11102 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
11107 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11108 << ReadableName << PointeeTy << DestTy << DSR
11111 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11112 << ActionIdx << SSR);
11148 if (CAT->getZExtSize() <= 1)
11156void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11160 unsigned NumArgs =
Call->getNumArgs();
11161 if ((NumArgs != 3) && (NumArgs != 4))
11166 const Expr *CompareWithSrc =
nullptr;
11169 Call->getBeginLoc(),
Call->getRParenLoc()))
11174 CompareWithSrc = Ex;
11177 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11178 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11179 SizeCall->getNumArgs() == 1)
11184 if (!CompareWithSrc)
11191 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11195 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11196 if (!CompareWithSrcDRE ||
11200 const Expr *OriginalSizeArg =
Call->getArg(2);
11201 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11208 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11212 SmallString<128> sizeString;
11213 llvm::raw_svector_ostream
OS(sizeString);
11218 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11225 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11226 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11227 return D1->getDecl() == D2->getDecl();
11232 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11241void Sema::CheckStrncatArguments(
const CallExpr *CE,
11256 unsigned PatternType = 0;
11264 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11265 if (BE->getOpcode() == BO_Sub) {
11266 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11267 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11278 if (PatternType == 0)
11287 if (
SM.isMacroArgExpansion(SL)) {
11288 SL =
SM.getSpellingLoc(SL);
11289 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11294 QualType DstTy = DstArg->
getType();
11297 if (!isKnownSizeArray) {
11298 if (PatternType == 1)
11299 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11301 Diag(SL, diag::warn_strncat_src_size) << SR;
11305 if (PatternType == 1)
11306 Diag(SL, diag::warn_strncat_large_size) << SR;
11308 Diag(SL, diag::warn_strncat_src_size) << SR;
11310 SmallString<128> sizeString;
11311 llvm::raw_svector_ostream
OS(sizeString);
11319 Diag(SL, diag::note_strncat_wrong_size)
11324void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11333void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11335 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11336 const Decl *D = Lvalue->getDecl();
11337 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11338 if (!DD->getType()->isReferenceType())
11339 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11343 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11344 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11345 Lvalue->getMemberDecl());
11348void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11350 const auto *Lambda = dyn_cast<LambdaExpr>(
11355 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11356 << CalleeName << 2 ;
11359void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11361 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11362 if (Var ==
nullptr)
11366 << CalleeName << 0 << Var;
11369void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11372 llvm::raw_svector_ostream
OS(SizeString);
11375 if (Kind == clang::CK_BitCast &&
11376 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11378 if (Kind == clang::CK_IntegralToPointer &&
11380 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11383 switch (
Cast->getCastKind()) {
11384 case clang::CK_BitCast:
11385 case clang::CK_IntegralToPointer:
11386 case clang::CK_FunctionToPointerDecay:
11395 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11396 << CalleeName << 0 <<
OS.str();
11400void Sema::CheckFreeArguments(
const CallExpr *E) {
11401 const std::string CalleeName =
11406 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11408 case UnaryOperator::Opcode::UO_AddrOf:
11409 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11410 case UnaryOperator::Opcode::UO_Plus:
11411 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11416 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11418 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11420 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11421 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11422 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11428 << CalleeName << 1 ;
11433 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11434 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11438Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11447 Diag(ReturnLoc, diag::warn_null_ret)
11457 if (Op == OO_New || Op == OO_Array_New) {
11458 const FunctionProtoType *Proto
11462 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11468 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11473 if (
Context.getTargetInfo().getTriple().isPPC64())
11485 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11486 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11487 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11488 return FPLiteral && FPCast;
11491 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11497 llvm::APFloat TargetC = FPLiteral->
getValue();
11498 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11499 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11503 Diag(Loc, diag::warn_float_compare_literal)
11504 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11517 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11518 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11519 if (DRL->getDecl() == DRR->getDecl())
11527 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11528 if (FLL->isExact())
11530 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11531 if (FLR->isExact())
11535 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11536 CL &&
CL->getBuiltinCallee())
11539 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11540 CR && CR->getBuiltinCallee())
11544 Diag(Loc, diag::warn_floatingpoint_eq)
11565 IntRange(
unsigned Width,
bool NonNegative)
11566 : Width(Width), NonNegative(NonNegative) {}
11569 unsigned valueBits()
const {
11570 return NonNegative ? Width : Width - 1;
11574 static IntRange forBoolType() {
11575 return IntRange(1,
true);
11579 static IntRange forValueOfType(ASTContext &
C, QualType T) {
11580 return forValueOfCanonicalType(
C,
11585 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *T) {
11588 if (
const auto *VT = dyn_cast<VectorType>(T))
11589 T = VT->getElementType().getTypePtr();
11590 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11591 T = MT->getElementType().getTypePtr();
11592 if (
const auto *CT = dyn_cast<ComplexType>(T))
11593 T = CT->getElementType().getTypePtr();
11594 if (
const auto *AT = dyn_cast<AtomicType>(T))
11595 T = AT->getValueType().getTypePtr();
11596 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11597 T = OBT->getUnderlyingType().getTypePtr();
11599 if (!
C.getLangOpts().CPlusPlus) {
11602 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11607 if (
Enum->isFixed()) {
11608 return IntRange(
C.getIntWidth(QualType(T, 0)),
11609 !
Enum->getIntegerType()->isSignedIntegerType());
11612 unsigned NumPositive =
Enum->getNumPositiveBits();
11613 unsigned NumNegative =
Enum->getNumNegativeBits();
11615 if (NumNegative == 0)
11616 return IntRange(NumPositive,
true);
11618 return IntRange(std::max(NumPositive + 1, NumNegative),
11622 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11623 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11636 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *T) {
11639 if (
const VectorType *VT = dyn_cast<VectorType>(T))
11640 T = VT->getElementType().getTypePtr();
11641 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11642 T = MT->getElementType().getTypePtr();
11643 if (
const ComplexType *CT = dyn_cast<ComplexType>(T))
11644 T = CT->getElementType().getTypePtr();
11645 if (
const AtomicType *AT = dyn_cast<AtomicType>(T))
11646 T = AT->getValueType().getTypePtr();
11648 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11649 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11650 T = OBT->getUnderlyingType().getTypePtr();
11652 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11653 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11662 static IntRange
join(IntRange L, IntRange R) {
11663 bool Unsigned = L.NonNegative &&
R.NonNegative;
11664 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11665 L.NonNegative &&
R.NonNegative);
11669 static IntRange bit_and(IntRange L, IntRange R) {
11670 unsigned Bits = std::max(L.Width,
R.Width);
11671 bool NonNegative =
false;
11672 if (L.NonNegative) {
11673 Bits = std::min(Bits, L.Width);
11674 NonNegative =
true;
11676 if (
R.NonNegative) {
11677 Bits = std::min(Bits,
R.Width);
11678 NonNegative =
true;
11680 return IntRange(Bits, NonNegative);
11684 static IntRange sum(IntRange L, IntRange R) {
11685 bool Unsigned = L.NonNegative &&
R.NonNegative;
11686 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11691 static IntRange difference(IntRange L, IntRange R) {
11695 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11696 bool Unsigned = L.NonNegative &&
R.Width == 0;
11697 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11703 static IntRange product(IntRange L, IntRange R) {
11707 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11708 bool Unsigned = L.NonNegative &&
R.NonNegative;
11709 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11714 static IntRange rem(IntRange L, IntRange R) {
11718 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11726 if (value.isSigned() && value.isNegative())
11727 return IntRange(value.getSignificantBits(),
false);
11729 if (value.getBitWidth() > MaxWidth)
11730 value = value.trunc(MaxWidth);
11734 return IntRange(value.getActiveBits(),
true);
11738 if (result.
isInt())
11745 R = IntRange::join(R, El);
11753 return IntRange::join(R, I);
11768 Ty = AtomicRHS->getValueType();
11787 bool InConstantContext,
11788 bool Approximate) {
11799 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11800 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11804 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11806 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11807 CE->getCastKind() == CK_BooleanToSignedIntegral;
11810 if (!isIntegerCast)
11811 return OutputTypeRange;
11814 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11815 InConstantContext, Approximate);
11817 return std::nullopt;
11820 if (SubRange->Width >= OutputTypeRange.Width)
11821 return OutputTypeRange;
11825 return IntRange(SubRange->Width,
11826 SubRange->NonNegative || OutputTypeRange.NonNegative);
11829 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11832 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11834 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11835 InConstantContext, Approximate);
11840 Expr *TrueExpr = CO->getTrueExpr();
11842 return std::nullopt;
11844 std::optional<IntRange> L =
11847 return std::nullopt;
11849 Expr *FalseExpr = CO->getFalseExpr();
11851 return std::nullopt;
11853 std::optional<IntRange> R =
11856 return std::nullopt;
11858 return IntRange::join(*L, *R);
11861 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11862 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11864 switch (BO->getOpcode()) {
11866 llvm_unreachable(
"builtin <=> should have class type");
11877 return IntRange::forBoolType();
11906 Combine = IntRange::bit_and;
11914 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11915 if (I->getValue() == 1) {
11916 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11917 return IntRange(R.Width,
true);
11927 case BO_ShrAssign: {
11929 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11931 return std::nullopt;
11935 if (std::optional<llvm::APSInt> shift =
11936 BO->getRHS()->getIntegerConstantExpr(
C)) {
11937 if (shift->isNonNegative()) {
11938 if (shift->uge(L->Width))
11939 L->Width = (L->NonNegative ? 0 : 1);
11941 L->Width -= shift->getZExtValue();
11955 Combine = IntRange::sum;
11959 if (BO->getLHS()->getType()->isPointerType())
11962 Combine = IntRange::difference;
11967 Combine = IntRange::product;
11976 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11978 return std::nullopt;
11981 if (std::optional<llvm::APSInt> divisor =
11982 BO->getRHS()->getIntegerConstantExpr(
C)) {
11983 unsigned log2 = divisor->logBase2();
11984 if (
log2 >= L->Width)
11985 L->Width = (L->NonNegative ? 0 : 1);
11987 L->Width = std::min(L->Width -
log2, MaxWidth);
11995 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11997 return std::nullopt;
11999 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12003 Combine = IntRange::rem;
12015 unsigned opWidth =
C.getIntWidth(T);
12017 InConstantContext, Approximate);
12019 return std::nullopt;
12022 InConstantContext, Approximate);
12024 return std::nullopt;
12026 IntRange
C = Combine(*L, *R);
12027 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
12028 C.Width = std::min(
C.Width, MaxWidth);
12032 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12033 switch (UO->getOpcode()) {
12036 return IntRange::forBoolType();
12050 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12053 return std::nullopt;
12058 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12068 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12071 return std::nullopt;
12076 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12086 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
12087 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
12091 return IntRange(BitField->getBitWidthValue(),
12092 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12095 return std::nullopt;
12101 bool InConstantContext,
12102 bool Approximate) {
12111 const llvm::fltSemantics &Src,
12112 const llvm::fltSemantics &Tgt) {
12113 llvm::APFloat truncated = value;
12116 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12117 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12119 return truncated.bitwiseIsEqual(value);
12128 const llvm::fltSemantics &Src,
12129 const llvm::fltSemantics &Tgt) {
12153 bool IsListInit =
false);
12168 return MacroName !=
"YES" && MacroName !=
"NO" &&
12169 MacroName !=
"true" && MacroName !=
"false";
12177 (!E->
getType()->isSignedIntegerType() ||
12192struct PromotedRange {
12194 llvm::APSInt PromotedMin;
12196 llvm::APSInt PromotedMax;
12198 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12200 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12201 else if (
R.Width >= BitWidth && !
Unsigned) {
12205 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12206 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12208 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12209 .extOrTrunc(BitWidth);
12210 PromotedMin.setIsUnsigned(
Unsigned);
12212 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12213 .extOrTrunc(BitWidth);
12214 PromotedMax.setIsUnsigned(
Unsigned);
12219 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12229 InRangeFlag = 0x40,
12232 Min =
LE | InRangeFlag,
12233 InRange = InRangeFlag,
12234 Max =
GE | InRangeFlag,
12237 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12242 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12243 Value.isUnsigned() == PromotedMin.isUnsigned());
12244 if (!isContiguous()) {
12245 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12246 if (
Value.isMinValue())
return Min;
12247 if (
Value.isMaxValue())
return Max;
12248 if (
Value >= PromotedMin)
return InRange;
12249 if (
Value <= PromotedMax)
return InRange;
12253 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12254 case -1:
return Less;
12255 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12257 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12258 case -1:
return InRange;
12259 case 0:
return Max;
12264 llvm_unreachable(
"impossible compare result");
12267 static std::optional<StringRef>
12269 if (Op == BO_Cmp) {
12271 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12273 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12274 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12275 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12276 return std::nullopt;
12283 }
else if (Op == BO_NE) {
12287 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12294 if (Op == BO_GE || Op == BO_LE)
12295 std::swap(TrueFlag, FalseFlag);
12298 return StringRef(
"true");
12300 return StringRef(
"false");
12301 return std::nullopt;
12308 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12309 if (ICE->getCastKind() != CK_IntegralCast &&
12310 ICE->getCastKind() != CK_NoOp)
12312 E = ICE->getSubExpr();
12321 enum ConstantValueKind {
12326 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12327 return BL->getValue() ? ConstantValueKind::LiteralTrue
12328 : ConstantValueKind::LiteralFalse;
12329 return ConstantValueKind::Miscellaneous;
12334 const llvm::APSInt &
Value,
12335 bool RhsConstant) {
12351 if (
Constant->getType()->isEnumeralType() &&
12357 if (!OtherValueRange)
12362 OtherT = AT->getValueType();
12363 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12367 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12373 bool OtherIsBooleanDespiteType =
12375 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12376 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12380 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12381 Value.isUnsigned());
12382 auto Cmp = OtherPromotedValueRange.compare(
Value);
12389 bool TautologicalTypeCompare =
false;
12391 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12392 Value.isUnsigned());
12393 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12396 TautologicalTypeCompare =
true;
12404 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12413 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12419 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12420 Other->getType()->isUnsignedIntegerOrEnumerationType())
12421 TautologicalTypeCompare =
true;
12426 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12427 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12431 llvm::raw_svector_ostream OS(PrettySourceValue);
12433 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12434 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12435 Constant->IgnoreParenImpCasts())) {
12436 OS << (BL->getValue() ?
"YES" :
"NO");
12441 if (!TautologicalTypeCompare) {
12443 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12449 if (IsObjCSignedCharBool) {
12451 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12452 << OS.str() << *
Result);
12459 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12463 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12464 : diag::warn_tautological_bool_compare)
12466 << OtherIsBooleanDespiteType << *
Result
12473 ? diag::warn_unsigned_enum_always_true_comparison
12474 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12475 : diag::warn_unsigned_always_true_comparison)
12476 : diag::warn_tautological_constant_compare;
12512 if (T->isIntegralType(S.
Context)) {
12513 std::optional<llvm::APSInt> RHSValue =
12515 std::optional<llvm::APSInt> LHSValue =
12519 if (RHSValue && LHSValue)
12523 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12525 const bool RhsConstant = (
bool)RHSValue;
12526 Expr *Const = RhsConstant ? RHS : LHS;
12528 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12537 if (!T->hasUnsignedIntegerRepresentation()) {
12551 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12553 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12559 Expr *signedOperand, *unsignedOperand;
12562 "unsigned comparison between two signed integer expressions?");
12563 signedOperand = LHS;
12564 unsignedOperand = RHS;
12566 signedOperand = RHS;
12567 unsignedOperand = LHS;
12573 std::optional<IntRange> signedRange =
12585 if (signedRange->NonNegative)
12597 if (!unsignedRange)
12602 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12604 if (unsignedRange->Width < comparisonWidth)
12609 S.
PDiag(diag::warn_mixed_sign_comparison)
12628 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12633 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12634 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12635 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12636 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12637 << BitfieldEnumDecl;
12644 Init->isValueDependent() ||
12645 Init->isTypeDependent())
12648 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12658 const PreferredTypeAttr *PTAttr =
nullptr;
12660 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12662 ED = PTAttr->getType()->getAsEnumDecl();
12670 bool SignedEnum = ED->getNumNegativeBits() > 0;
12677 unsigned DiagID = 0;
12678 if (SignedEnum && !SignedBitfield) {
12681 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12683 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12684 }
else if (SignedBitfield && !SignedEnum &&
12685 ED->getNumPositiveBits() == FieldWidth) {
12688 ? diag::warn_signed_bitfield_enum_conversion
12689 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12692 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12697 << SignedEnum << TypeRange;
12699 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12706 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12707 ED->getNumNegativeBits())
12708 : ED->getNumPositiveBits();
12711 if (BitsNeeded > FieldWidth) {
12715 ? diag::warn_bitfield_too_small_for_enum
12716 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12717 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12721 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12731 unsigned OriginalWidth =
Value.getBitWidth();
12737 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12738 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12745 if (!
Value.isSigned() ||
Value.isNegative())
12746 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12747 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12748 OriginalWidth =
Value.getSignificantBits();
12750 if (OriginalWidth <= FieldWidth)
12754 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12758 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12759 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12763 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12765 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12766 ? diag::warn_impcast_single_bit_bitield_precision_constant
12767 : diag::warn_impcast_bitfield_precision_constant)
12768 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12769 <<
Init->getSourceRange();
12806 bool PruneControlFlow =
false) {
12813 if (T.hasAddressSpace())
12815 if (PruneControlFlow) {
12829 bool PruneControlFlow =
false) {
12836 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
12841 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12842 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12847 llvm::APFloat
Value(0.0);
12853 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12858 diag::warn_impcast_float_integer, PruneWarnings);
12861 bool isExact =
false;
12864 T->hasUnsignedIntegerRepresentation());
12865 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
12866 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12874 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12875 precision = (precision * 59 + 195) / 196;
12876 Value.toString(PrettySourceValue, precision);
12880 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12881 << PrettySourceValue);
12884 if (
Result == llvm::APFloat::opOK && isExact) {
12885 if (IsLiteral)
return;
12886 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
12892 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
12895 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12896 : diag::warn_impcast_float_to_integer_out_of_range,
12899 unsigned DiagID = 0;
12902 DiagID = diag::warn_impcast_literal_float_to_integer;
12903 }
else if (IntegerValue == 0) {
12904 if (
Value.isZero()) {
12906 diag::warn_impcast_float_integer, PruneWarnings);
12909 DiagID = diag::warn_impcast_float_to_integer_zero;
12911 if (IntegerValue.isUnsigned()) {
12912 if (!IntegerValue.isMaxValue()) {
12914 diag::warn_impcast_float_integer, PruneWarnings);
12917 if (!IntegerValue.isMaxSignedValue() &&
12918 !IntegerValue.isMinSignedValue()) {
12920 diag::warn_impcast_float_integer, PruneWarnings);
12924 DiagID = diag::warn_impcast_float_to_integer;
12929 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12931 IntegerValue.toString(PrettyTargetValue);
12933 if (PruneWarnings) {
12937 << PrettySourceValue << PrettyTargetValue
12950 "Must be compound assignment operation");
12961 ->getComputationResultType()
12968 if (ResultBT->isInteger())
12970 E->
getExprLoc(), diag::warn_impcast_float_integer);
12972 if (!ResultBT->isFloatingPoint())
12981 diag::warn_impcast_float_result_precision);
12986 if (!Range.Width)
return "0";
12988 llvm::APSInt ValueInRange =
Value;
12989 ValueInRange.setIsSigned(!Range.NonNegative);
12990 ValueInRange = ValueInRange.trunc(Range.Width);
12991 return toString(ValueInRange, 10);
13001 const Type *Source =
13003 if (
Target->isDependentType())
13006 const auto *FloatCandidateBT =
13007 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13008 const Type *BoolCandidateType = ToBool ?
Target : Source;
13011 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13016 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13022 S, TheCall->
getArg(I - 1),
false));
13024 S, TheCall->
getArg(I + 1),
false));
13029 diag::warn_impcast_floating_point_to_bool);
13044 if (!IsGNUNullExpr && !HasNullPtrType)
13048 if (T->isAnyPointerType() || T->isBlockPointerType() ||
13049 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
13052 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13065 if (IsGNUNullExpr && Loc.
isMacroID()) {
13068 if (MacroName ==
"NULL")
13076 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13090 const char FirstLiteralCharacter =
13092 if (FirstLiteralCharacter ==
'0')
13098 if (CC.
isValid() && T->isCharType()) {
13099 const char FirstContextCharacter =
13101 if (FirstContextCharacter ==
'{')
13109 const auto *IL = dyn_cast<IntegerLiteral>(E);
13111 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13112 if (UO->getOpcode() == UO_Minus)
13113 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13124 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13128 if (Opc == BO_Shl) {
13131 if (LHS && LHS->getValue() == 0)
13132 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13134 RHS->getValue().isNonNegative() &&
13136 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13137 << (
Result.Val.getInt() != 0);
13139 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13146 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13151 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13152 (RHS->getValue() == 0 || RHS->getValue() == 1))
13155 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13156 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13164 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13170 if (Source->isChar16Type() &&
Target->isChar32Type())
13176 llvm::APSInt
Value(32);
13178 bool IsASCII =
Value <= 0x7F;
13179 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13180 bool ConversionPreservesSemantics =
13181 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13183 if (!ConversionPreservesSemantics) {
13184 auto IsSingleCodeUnitCP = [](
const QualType &T,
13185 const llvm::APSInt &
Value) {
13186 if (T->isChar8Type())
13187 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13188 if (T->isChar16Type())
13189 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13190 assert(T->isChar32Type());
13191 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13194 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13203 LosesPrecision ? diag::warn_impcast_unicode_precision
13204 : diag::warn_impcast_unicode_char_type);
13209 From =
Context.getCanonicalType(From);
13210 To =
Context.getCanonicalType(To);
13213 From = MaybePointee;
13220 if (FromFn->getCFIUncheckedCalleeAttr() &&
13221 !ToFn->getCFIUncheckedCalleeAttr())
13229 bool *ICContext,
bool IsListInit) {
13234 if (Source ==
Target)
return;
13235 if (
Target->isDependentType())
return;
13245 if (Source->isAtomicType())
13249 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13255 diag::warn_impcast_string_literal_to_bool);
13261 diag::warn_impcast_objective_c_literal_to_bool);
13263 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13275 if (
ObjC().isSignedCharBool(T) && Source->isIntegralType(
Context)) {
13278 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13280 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13289 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13291 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13302 diag::err_impcast_incompatible_type);
13307 ? diag::err_impcast_complex_scalar
13308 : diag::warn_impcast_complex_scalar);
13317 if (
Target->isSveVLSBuiltinType() &&
13324 if (
Target->isRVVVLSBuiltinType() &&
13334 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_vector_scalar);
13342 diag::warn_hlsl_impcast_vector_truncation);
13354 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13355 Target = VecTy->getElementType().getTypePtr();
13359 if (
Target->isScalarType())
13360 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_matrix_scalar);
13368 diag::warn_hlsl_impcast_matrix_truncation);
13374 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13375 Target = MatTy->getElementType().getTypePtr();
13377 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13383 const Type *OriginalTarget =
Context.getCanonicalType(T).getTypePtr();
13386 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13388 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13427 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_float_precision);
13430 else if (Order < 0) {
13434 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_double_promotion);
13440 if (TargetBT && TargetBT->
isInteger()) {
13467 diag::warn_impcast_floating_point_to_bool);
13475 if (Source->isFixedPointType()) {
13476 if (
Target->isUnsaturatedFixedPointType()) {
13480 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13481 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(T);
13482 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(T);
13485 PDiag(diag::warn_impcast_fixed_point_range)
13486 <<
Value.toString() << T
13492 }
else if (
Target->isIntegerType()) {
13496 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13499 llvm::APSInt IntResult = FXResult.convertToInt(
13500 Context.getIntWidth(T),
Target->isSignedIntegerOrEnumerationType(),
13505 PDiag(diag::warn_impcast_fixed_point_range)
13506 << FXResult.toString() << T
13513 }
else if (
Target->isUnsaturatedFixedPointType()) {
13514 if (Source->isIntegerType()) {
13521 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13522 Value,
Context.getFixedPointSemantics(T), &Overflowed);
13526 PDiag(diag::warn_impcast_fixed_point_range)
13547 unsigned int SourcePrecision =
SourceRange->Width;
13551 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13554 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13555 SourcePrecision > TargetPrecision) {
13557 if (std::optional<llvm::APSInt> SourceInt =
13562 llvm::APFloat TargetFloatValue(
13564 llvm::APFloat::opStatus ConversionStatus =
13565 TargetFloatValue.convertFromAPInt(
13567 llvm::APFloat::rmNearestTiesToEven);
13569 if (ConversionStatus != llvm::APFloat::opOK) {
13571 SourceInt->toString(PrettySourceValue, 10);
13573 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13577 PDiag(diag::warn_impcast_integer_float_precision_constant)
13578 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13584 diag::warn_impcast_integer_float_precision);
13593 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13598 if (
Target->isBooleanType())
13602 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13606 if (!Source->isIntegerType() || !
Target->isIntegerType())
13611 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13614 if (
ObjC().isSignedCharBool(T) && !Source->isCharType() &&
13617 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13622 if (!LikelySourceRange)
13625 IntRange SourceTypeRange =
13626 IntRange::forTargetOfCanonicalType(
Context, Source);
13627 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13629 if (LikelySourceRange->Width > TargetRange.Width) {
13633 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13634 if (TargetOBT->isWrapKind()) {
13641 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13642 if (SourceOBT->isWrapKind()) {
13652 llvm::APSInt
Value(32);
13662 PDiag(diag::warn_impcast_integer_precision_constant)
13663 << PrettySourceValue << PrettyTargetValue
13673 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13674 if (UO->getOpcode() == UO_Minus)
13676 *
this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
13679 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13680 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_integer_64_32,
13683 diag::warn_impcast_integer_precision);
13686 if (TargetRange.Width > SourceTypeRange.Width) {
13687 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13688 if (UO->getOpcode() == UO_Minus)
13689 if (Source->isUnsignedIntegerType()) {
13690 if (
Target->isUnsignedIntegerType())
13692 diag::warn_impcast_high_order_zero_bits);
13693 if (
Target->isSignedIntegerType())
13695 diag::warn_impcast_nonnegative_result);
13699 if (TargetRange.Width == LikelySourceRange->Width &&
13700 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13701 Source->isSignedIntegerType()) {
13715 PDiag(diag::warn_impcast_integer_precision_constant)
13716 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13726 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13727 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13728 LikelySourceRange->Width == TargetRange.Width))) {
13732 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13734 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13738 unsigned DiagID = diag::warn_impcast_integer_sign;
13746 DiagID = diag::warn_impcast_integer_sign_conditional;
13758 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_int_to_enum);
13763 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13765 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13766 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13767 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13768 TargetEnum->getDecl()->hasNameForLinkage() &&
13769 SourceEnum != TargetEnum) {
13774 diag::warn_impcast_different_enum_types);
13788 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13801 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13802 TrueExpr = BCO->getCommon();
13804 bool Suspicious =
false;
13808 if (T->isBooleanType())
13813 if (!Suspicious)
return;
13816 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13821 if (E->
getType() == T)
return;
13823 Suspicious =
false;
13828 E->
getType(), CC, &Suspicious);
13845struct AnalyzeImplicitConversionsWorkItem {
13854 bool ExtraCheckForImplicitConversion,
13857 WorkList.push_back({E, CC,
false});
13859 if (ExtraCheckForImplicitConversion && E->
getType() != T)
13866 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13868 Expr *OrigE = Item.E;
13887 Expr *SourceExpr = E;
13892 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13893 if (
auto *Src = OVE->getSourceExpr())
13896 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13897 if (UO->getOpcode() == UO_Not &&
13898 UO->getSubExpr()->isKnownToHaveBooleanValue())
13899 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13903 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13904 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13905 BO->getLHS()->isKnownToHaveBooleanValue() &&
13906 BO->getRHS()->isKnownToHaveBooleanValue() &&
13907 BO->getLHS()->HasSideEffects(S.
Context) &&
13908 BO->getRHS()->HasSideEffects(S.
Context)) {
13919 if (SR.str() ==
"&" || SR.str() ==
"|") {
13921 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13922 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13925 BO->getOperatorLoc(),
13926 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13927 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13929 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13947 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13953 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13959 if (SourceExpr->
getType() != T)
13968 for (
auto *SE : POE->semantics())
13969 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13970 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13974 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13975 E = CE->getSubExpr();
13981 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13982 if (InitListE->getNumInits() == 1) {
13983 E = InitListE->getInit(0);
13990 WorkList.push_back({E, CC, IsListInit});
13994 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13995 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13999 if (OutArgE->isInOut())
14000 WorkList.push_back(
14001 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14002 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14008 if (BO->isComparisonOp())
14012 if (BO->getOpcode() == BO_Assign)
14015 if (BO->isAssignmentOp())
14031 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14033 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14037 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14038 if (ChildExpr == CSE->getOperand())
14044 if (IsLogicalAndOperator &&
14049 WorkList.push_back({ChildExpr, CC, IsListInit});
14063 if (
U->getOpcode() == UO_LNot) {
14065 }
else if (
U->getOpcode() != UO_AddrOf) {
14066 if (
U->getSubExpr()->getType()->isAtomicType())
14067 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14068 diag::warn_atomic_implicit_seq_cst);
14079 WorkList.push_back({OrigE, CC, IsListInit});
14080 while (!WorkList.empty())
14092 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14095 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14096 if (!M->getMemberDecl()->getType()->isReferenceType())
14098 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14099 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14101 FD =
Call->getDirectCallee();
14110 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14124 if (
SM.isMacroBodyExpansion(Loc))
14126 Loc =
SM.getImmediateMacroCallerLoc(Loc);
14150 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14151 : diag::warn_this_bool_conversion;
14156 bool IsAddressOf =
false;
14158 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14159 if (UO->getOpcode() != UO_AddrOf)
14161 IsAddressOf =
true;
14162 E = UO->getSubExpr();
14166 unsigned DiagID = IsCompare
14167 ? diag::warn_address_of_reference_null_compare
14168 : diag::warn_address_of_reference_bool_conversion;
14176 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14179 llvm::raw_string_ostream S(Str);
14181 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14182 : diag::warn_cast_nonnull_to_bool;
14185 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14190 if (
auto *Callee =
Call->getDirectCallee()) {
14191 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14192 ComplainAboutNonnullParamOrCall(A);
14201 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14202 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14203 MRecordDecl && MRecordDecl->isLambda()) {
14206 << MRecordDecl->getSourceRange() << Range << IsEqual;
14216 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14217 D = M->getMemberDecl();
14225 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14228 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14229 ComplainAboutNonnullParamOrCall(A);
14233 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14237 auto ParamIter = llvm::find(FD->
parameters(), PV);
14239 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14243 ComplainAboutNonnullParamOrCall(
NonNull);
14248 if (ArgNo.getASTIndex() == ParamNo) {
14249 ComplainAboutNonnullParamOrCall(
NonNull);
14260 const bool IsFunction = T->isFunctionType();
14263 if (IsAddressOf && IsFunction) {
14268 if (!IsAddressOf && !IsFunction && !IsArray)
14273 llvm::raw_string_ostream S(Str);
14276 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14277 : diag::warn_impcast_pointer_to_bool;
14284 DiagType = AddressOf;
14285 else if (IsFunction)
14286 DiagType = FunctionPointer;
14288 DiagType = ArrayPointer;
14290 llvm_unreachable(
"Could not determine diagnostic.");
14292 << Range << IsEqual;
14305 if (ReturnType.
isNull())
14336 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14337 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14339 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14340 Target->isUnsignedIntegerType()) {
14344 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14345 : diag::warn_impcast_overflow_behavior_pedantic;
14349 ? diag::warn_impcast_overflow_behavior_assignment
14350 : diag::warn_impcast_overflow_behavior;
14356 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14357 if (TargetOBT->isWrapKind()) {
14377 CheckArrayAccess(E);
14387void Sema::CheckForIntOverflow (
const Expr *E) {
14389 SmallVector<const Expr *, 2> Exprs(1, E);
14392 const Expr *OriginalE = Exprs.pop_back_val();
14401 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14402 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14405 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14406 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14407 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14409 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14410 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14411 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14412 Exprs.push_back(Temporary->getSubExpr());
14413 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14414 Exprs.push_back(
Array->getIdx());
14415 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14416 Exprs.push_back(Compound->getInitializer());
14417 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14418 New &&
New->isArray()) {
14419 if (
auto ArraySize =
New->getArraySize())
14420 Exprs.push_back(*ArraySize);
14421 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14422 Exprs.push_back(MTE->getSubExpr());
14423 }
while (!Exprs.empty());
14431 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14438 class SequenceTree {
14440 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14441 unsigned Parent : 31;
14442 LLVM_PREFERRED_TYPE(
bool)
14443 unsigned Merged : 1;
14445 SmallVector<Value, 8> Values;
14451 friend class SequenceTree;
14455 explicit Seq(
unsigned N) : Index(N) {}
14458 Seq() : Index(0) {}
14461 SequenceTree() { Values.push_back(
Value(0)); }
14462 Seq root()
const {
return Seq(0); }
14467 Seq allocate(
Seq Parent) {
14468 Values.push_back(
Value(Parent.Index));
14469 return Seq(Values.size() - 1);
14474 Values[S.Index].Merged =
true;
14480 bool isUnsequenced(
Seq Cur,
Seq Old) {
14481 unsigned C = representative(Cur.Index);
14482 unsigned Target = representative(Old.Index);
14486 C = Values[
C].Parent;
14493 unsigned representative(
unsigned K) {
14494 if (Values[K].Merged)
14496 return Values[K].Parent = representative(Values[K].Parent);
14502 using Object =
const NamedDecl *;
14516 UK_ModAsSideEffect,
14518 UK_Count = UK_ModAsSideEffect + 1
14524 const Expr *UsageExpr =
nullptr;
14525 SequenceTree::Seq
Seq;
14531 Usage Uses[UK_Count];
14534 bool Diagnosed =
false;
14538 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14546 UsageInfoMap UsageMap;
14549 SequenceTree::Seq Region;
14553 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14557 SmallVectorImpl<const Expr *> &WorkList;
14564 struct SequencedSubexpression {
14565 SequencedSubexpression(SequenceChecker &
Self)
14566 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14567 Self.ModAsSideEffect = &ModAsSideEffect;
14570 ~SequencedSubexpression() {
14571 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14575 UsageInfo &UI =
Self.UsageMap[M.first];
14576 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14577 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14578 SideEffectUsage = M.second;
14580 Self.ModAsSideEffect = OldModAsSideEffect;
14583 SequenceChecker &
Self;
14584 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14585 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14592 class EvaluationTracker {
14594 EvaluationTracker(SequenceChecker &
Self)
14596 Self.EvalTracker =
this;
14599 ~EvaluationTracker() {
14600 Self.EvalTracker = Prev;
14602 Prev->EvalOK &= EvalOK;
14605 bool evaluate(
const Expr *E,
bool &
Result) {
14610 Self.SemaRef.isConstantEvaluatedContext());
14615 SequenceChecker &
Self;
14616 EvaluationTracker *Prev;
14617 bool EvalOK =
true;
14618 } *EvalTracker =
nullptr;
14622 Object getObject(
const Expr *E,
bool Mod)
const {
14624 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14625 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14626 return getObject(UO->getSubExpr(), Mod);
14627 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14628 if (BO->getOpcode() == BO_Comma)
14629 return getObject(BO->getRHS(), Mod);
14630 if (Mod && BO->isAssignmentOp())
14631 return getObject(BO->getLHS(), Mod);
14632 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14635 return ME->getMemberDecl();
14636 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14645 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14647 Usage &U = UI.Uses[UK];
14648 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14652 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14653 ModAsSideEffect->push_back(std::make_pair(O, U));
14655 U.UsageExpr = UsageExpr;
14665 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14666 UsageKind OtherKind,
bool IsModMod) {
14670 const Usage &U = UI.Uses[OtherKind];
14671 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14674 const Expr *Mod = U.UsageExpr;
14675 const Expr *ModOrUse = UsageExpr;
14676 if (OtherKind == UK_Use)
14677 std::swap(Mod, ModOrUse);
14681 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14682 : diag::warn_unsequenced_mod_use)
14683 << O << SourceRange(ModOrUse->
getExprLoc()));
14684 UI.Diagnosed =
true;
14713 void notePreUse(
Object O,
const Expr *UseExpr) {
14714 UsageInfo &UI = UsageMap[O];
14716 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14719 void notePostUse(
Object O,
const Expr *UseExpr) {
14720 UsageInfo &UI = UsageMap[O];
14721 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14723 addUsage(O, UI, UseExpr, UK_Use);
14726 void notePreMod(
Object O,
const Expr *ModExpr) {
14727 UsageInfo &UI = UsageMap[O];
14729 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14730 checkUsage(O, UI, ModExpr, UK_Use,
false);
14733 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14734 UsageInfo &UI = UsageMap[O];
14735 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14737 addUsage(O, UI, ModExpr, UK);
14741 SequenceChecker(Sema &S,
const Expr *E,
14742 SmallVectorImpl<const Expr *> &WorkList)
14743 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14747 (void)this->WorkList;
14750 void VisitStmt(
const Stmt *S) {
14754 void VisitExpr(
const Expr *E) {
14756 Base::VisitStmt(E);
14759 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14760 for (
auto *Sub : CSE->
children()) {
14761 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14776 void VisitCastExpr(
const CastExpr *E) {
14788 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14789 const Expr *SequencedAfter) {
14790 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14791 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14792 SequenceTree::Seq OldRegion = Region;
14795 SequencedSubexpression SeqBefore(*
this);
14796 Region = BeforeRegion;
14797 Visit(SequencedBefore);
14800 Region = AfterRegion;
14801 Visit(SequencedAfter);
14803 Region = OldRegion;
14805 Tree.merge(BeforeRegion);
14806 Tree.merge(AfterRegion);
14809 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14814 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14821 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14822 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14823 void VisitBinPtrMem(
const BinaryOperator *BO) {
14828 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14835 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14836 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14837 void VisitBinShlShr(
const BinaryOperator *BO) {
14841 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14848 void VisitBinComma(
const BinaryOperator *BO) {
14853 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14856 void VisitBinAssign(
const BinaryOperator *BO) {
14857 SequenceTree::Seq RHSRegion;
14858 SequenceTree::Seq LHSRegion;
14860 RHSRegion = Tree.allocate(Region);
14861 LHSRegion = Tree.allocate(Region);
14863 RHSRegion = Region;
14864 LHSRegion = Region;
14866 SequenceTree::Seq OldRegion = Region;
14882 SequencedSubexpression SeqBefore(*
this);
14883 Region = RHSRegion;
14887 Region = LHSRegion;
14891 notePostUse(O, BO);
14895 Region = LHSRegion;
14899 notePostUse(O, BO);
14901 Region = RHSRegion;
14909 Region = OldRegion;
14913 : UK_ModAsSideEffect);
14915 Tree.merge(RHSRegion);
14916 Tree.merge(LHSRegion);
14920 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14921 VisitBinAssign(CAO);
14924 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14925 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14926 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14929 return VisitExpr(UO);
14937 : UK_ModAsSideEffect);
14940 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14941 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14942 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14945 return VisitExpr(UO);
14949 notePostMod(O, UO, UK_ModAsSideEffect);
14952 void VisitBinLOr(
const BinaryOperator *BO) {
14958 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14959 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14960 SequenceTree::Seq OldRegion = Region;
14962 EvaluationTracker Eval(*
this);
14964 SequencedSubexpression Sequenced(*
this);
14965 Region = LHSRegion;
14972 bool EvalResult =
false;
14973 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14974 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14975 if (ShouldVisitRHS) {
14976 Region = RHSRegion;
14980 Region = OldRegion;
14981 Tree.merge(LHSRegion);
14982 Tree.merge(RHSRegion);
14985 void VisitBinLAnd(
const BinaryOperator *BO) {
14991 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14992 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14993 SequenceTree::Seq OldRegion = Region;
14995 EvaluationTracker Eval(*
this);
14997 SequencedSubexpression Sequenced(*
this);
14998 Region = LHSRegion;
15004 bool EvalResult =
false;
15005 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15006 bool ShouldVisitRHS = !EvalOK || EvalResult;
15007 if (ShouldVisitRHS) {
15008 Region = RHSRegion;
15012 Region = OldRegion;
15013 Tree.merge(LHSRegion);
15014 Tree.merge(RHSRegion);
15017 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15022 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15038 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15039 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15040 SequenceTree::Seq OldRegion = Region;
15042 EvaluationTracker Eval(*
this);
15044 SequencedSubexpression Sequenced(*
this);
15045 Region = ConditionRegion;
15055 bool EvalResult =
false;
15056 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15057 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15058 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15059 if (ShouldVisitTrueExpr) {
15060 Region = TrueRegion;
15063 if (ShouldVisitFalseExpr) {
15064 Region = FalseRegion;
15068 Region = OldRegion;
15069 Tree.merge(ConditionRegion);
15070 Tree.merge(TrueRegion);
15071 Tree.merge(FalseRegion);
15074 void VisitCallExpr(
const CallExpr *CE) {
15086 SequencedSubexpression Sequenced(*
this);
15091 SequenceTree::Seq CalleeRegion;
15092 SequenceTree::Seq OtherRegion;
15093 if (SemaRef.getLangOpts().CPlusPlus17) {
15094 CalleeRegion = Tree.allocate(Region);
15095 OtherRegion = Tree.allocate(Region);
15097 CalleeRegion = Region;
15098 OtherRegion = Region;
15100 SequenceTree::Seq OldRegion = Region;
15103 Region = CalleeRegion;
15105 SequencedSubexpression Sequenced(*this);
15106 Visit(CE->getCallee());
15108 Visit(CE->getCallee());
15112 Region = OtherRegion;
15116 Region = OldRegion;
15118 Tree.merge(CalleeRegion);
15119 Tree.merge(OtherRegion);
15137 return VisitCallExpr(CXXOCE);
15148 case OO_MinusEqual:
15150 case OO_SlashEqual:
15151 case OO_PercentEqual:
15152 case OO_CaretEqual:
15155 case OO_LessLessEqual:
15156 case OO_GreaterGreaterEqual:
15157 SequencingKind = RHSBeforeLHS;
15161 case OO_GreaterGreater:
15167 SequencingKind = LHSBeforeRHS;
15171 SequencingKind = LHSBeforeRest;
15175 SequencingKind = NoSequencing;
15179 if (SequencingKind == NoSequencing)
15180 return VisitCallExpr(CXXOCE);
15183 SequencedSubexpression Sequenced(*
this);
15186 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15187 "Should only get there with C++17 and above!");
15188 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15189 "Should only get there with an overloaded binary operator"
15190 " or an overloaded call operator!");
15192 if (SequencingKind == LHSBeforeRest) {
15193 assert(CXXOCE->getOperator() == OO_Call &&
15194 "We should only have an overloaded call operator here!");
15203 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15204 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15205 SequenceTree::Seq OldRegion = Region;
15207 assert(CXXOCE->getNumArgs() >= 1 &&
15208 "An overloaded call operator must have at least one argument"
15209 " for the postfix-expression!");
15210 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15211 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15212 CXXOCE->getNumArgs() - 1);
15216 Region = PostfixExprRegion;
15217 SequencedSubexpression Sequenced(*this);
15218 Visit(PostfixExpr);
15222 Region = ArgsRegion;
15223 for (const Expr *Arg : Args)
15226 Region = OldRegion;
15227 Tree.merge(PostfixExprRegion);
15228 Tree.merge(ArgsRegion);
15230 assert(CXXOCE->getNumArgs() == 2 &&
15231 "Should only have two arguments here!");
15232 assert((SequencingKind == LHSBeforeRHS ||
15233 SequencingKind == RHSBeforeLHS) &&
15234 "Unexpected sequencing kind!");
15238 const Expr *E1 = CXXOCE->getArg(0);
15239 const Expr *E2 = CXXOCE->getArg(1);
15240 if (SequencingKind == RHSBeforeLHS)
15243 return VisitSequencedExpressions(E1, E2);
15250 SequencedSubexpression Sequenced(*
this);
15253 return VisitExpr(CCE);
15256 SequenceExpressionsInOrder(
15262 return VisitExpr(ILE);
15265 SequenceExpressionsInOrder(ILE->
inits());
15277 SequenceTree::Seq Parent = Region;
15278 for (
const Expr *E : ExpressionList) {
15281 Region = Tree.allocate(Parent);
15282 Elts.push_back(Region);
15288 for (
unsigned I = 0; I < Elts.size(); ++I)
15289 Tree.merge(Elts[I]);
15293SequenceChecker::UsageInfo::UsageInfo() =
default;
15297void Sema::CheckUnsequencedOperations(
const Expr *E) {
15298 SmallVector<const Expr *, 8> WorkList;
15299 WorkList.push_back(E);
15300 while (!WorkList.empty()) {
15301 const Expr *Item = WorkList.pop_back_val();
15302 SequenceChecker(*
this, Item, WorkList);
15307 bool IsConstexpr) {
15310 CheckImplicitConversions(E, CheckLoc);
15312 CheckUnsequencedOperations(E);
15314 CheckForIntOverflow(E);
15327 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15331 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15335 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15349 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15353 bool CheckParameterNames) {
15354 bool HasInvalidParm =
false;
15356 assert(Param &&
"null in a parameter list");
15365 if (!Param->isInvalidDecl() &&
15367 diag::err_typecheck_decl_incomplete_type) ||
15369 diag::err_abstract_type_in_decl,
15371 Param->setInvalidDecl();
15372 HasInvalidParm =
true;
15377 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15381 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15389 QualType PType = Param->getOriginalType();
15397 if (!Param->isInvalidDecl()) {
15398 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15399 if (!ClassDecl->isInvalidDecl() &&
15400 !ClassDecl->hasIrrelevantDestructor() &&
15401 !ClassDecl->isDependentContext() &&
15402 ClassDecl->isParamDestroyedInCallee()) {
15414 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15415 if (!Param->getType().isConstQualified())
15416 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15420 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15425 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15426 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15431 if (!Param->isInvalidDecl() &&
15432 Param->getOriginalType()->isWebAssemblyTableType()) {
15433 Param->setInvalidDecl();
15434 HasInvalidParm =
true;
15435 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15439 return HasInvalidParm;
15442std::optional<std::pair<
15451static std::pair<CharUnits, CharUnits>
15459 if (
Base->isVirtual()) {
15466 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15473 DerivedType =
Base->getType();
15476 return std::make_pair(BaseAlignment, Offset);
15480static std::optional<std::pair<CharUnits, CharUnits>>
15486 return std::nullopt;
15491 return std::nullopt;
15495 CharUnits Offset = EltSize * IdxRes->getExtValue();
15498 return std::make_pair(P->first, P->second + Offset);
15504 return std::make_pair(
15505 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15511std::optional<std::pair<
15519 case Stmt::CStyleCastExprClass:
15520 case Stmt::CXXStaticCastExprClass:
15521 case Stmt::ImplicitCastExprClass: {
15523 const Expr *From = CE->getSubExpr();
15524 switch (CE->getCastKind()) {
15529 case CK_UncheckedDerivedToBase:
15530 case CK_DerivedToBase: {
15540 case Stmt::ArraySubscriptExprClass: {
15545 case Stmt::DeclRefExprClass: {
15549 if (!VD->getType()->isReferenceType()) {
15551 if (VD->hasDependentAlignment())
15560 case Stmt::MemberExprClass: {
15562 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15566 std::optional<std::pair<CharUnits, CharUnits>> P;
15575 return std::make_pair(P->first,
15578 case Stmt::UnaryOperatorClass: {
15588 case Stmt::BinaryOperatorClass: {
15600 return std::nullopt;
15605std::optional<std::pair<
15614 case Stmt::CStyleCastExprClass:
15615 case Stmt::CXXStaticCastExprClass:
15616 case Stmt::ImplicitCastExprClass: {
15618 const Expr *From = CE->getSubExpr();
15619 switch (CE->getCastKind()) {
15624 case CK_ArrayToPointerDecay:
15626 case CK_UncheckedDerivedToBase:
15627 case CK_DerivedToBase: {
15637 case Stmt::CXXThisExprClass: {
15642 case Stmt::UnaryOperatorClass: {
15648 case Stmt::BinaryOperatorClass: {
15657 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15658 std::swap(LHS, RHS);
15668 return std::nullopt;
15673 std::optional<std::pair<CharUnits, CharUnits>> P =
15677 return P->first.alignmentAtOffset(P->second);
15695 if (!DestPtr)
return;
15701 if (DestAlign.
isOne())
return;
15705 if (!SrcPtr)
return;
15716 if (SrcAlign >= DestAlign)
return;
15721 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15725void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15727 bool AllowOnePastEnd,
bool IndexNegated) {
15736 const Type *EffectiveType =
15740 Context.getAsConstantArrayType(BaseExpr->
getType());
15743 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15745 const Type *BaseType =
15747 bool IsUnboundedArray =
15749 Context, StrictFlexArraysLevel,
15752 (!IsUnboundedArray && BaseType->isDependentType()))
15760 if (IndexNegated) {
15761 index.setIsUnsigned(
false);
15765 if (IsUnboundedArray) {
15768 if (
index.isUnsigned() || !
index.isNegative()) {
15770 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15772 if (
index.getBitWidth() < AddrBits)
15774 std::optional<CharUnits> ElemCharUnits =
15775 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15778 if (!ElemCharUnits || ElemCharUnits->isZero())
15780 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15785 if (
index.getActiveBits() <= AddrBits) {
15787 llvm::APInt Product(
index);
15789 Product = Product.umul_ov(ElemBytes, Overflow);
15790 if (!Overflow && Product.getActiveBits() <= AddrBits)
15796 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15797 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15799 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15800 MaxElems = MaxElems.udiv(ElemBytes);
15803 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15804 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15809 PDiag(DiagID) << index << AddrBits
15810 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15811 << ElemBytes << MaxElems
15812 << MaxElems.getZExtValue()
15815 const NamedDecl *ND =
nullptr;
15817 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15819 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15821 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15822 ND = ME->getMemberDecl();
15826 PDiag(diag::note_array_declared_here) << ND);
15831 if (index.isUnsigned() || !index.isNegative()) {
15841 llvm::APInt size = ArrayTy->
getSize();
15843 if (BaseType != EffectiveType) {
15851 if (!ptrarith_typesize)
15852 ptrarith_typesize =
Context.getCharWidth();
15854 if (ptrarith_typesize != array_typesize) {
15856 uint64_t ratio = array_typesize / ptrarith_typesize;
15860 if (ptrarith_typesize * ratio == array_typesize)
15861 size *= llvm::APInt(size.getBitWidth(), ratio);
15865 if (size.getBitWidth() > index.getBitWidth())
15866 index = index.zext(size.getBitWidth());
15867 else if (size.getBitWidth() < index.getBitWidth())
15868 size = size.zext(index.getBitWidth());
15874 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15881 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15883 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15884 SourceLocation IndexLoc =
15886 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15891 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15892 : diag::warn_ptr_arith_exceeds_bounds;
15893 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15894 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15898 << index << ArrayTy->
desugar() << CastMsg
15901 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15903 DiagID = diag::warn_ptr_arith_precedes_bounds;
15904 if (index.isNegative()) index = -index;
15911 const NamedDecl *ND =
nullptr;
15913 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15915 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15917 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15918 ND = ME->getMemberDecl();
15922 PDiag(diag::note_array_declared_here) << ND);
15925void Sema::CheckArrayAccess(
const Expr *
expr) {
15926 int AllowOnePastEnd = 0;
15928 expr =
expr->IgnoreParenImpCasts();
15929 switch (
expr->getStmtClass()) {
15930 case Stmt::ArraySubscriptExprClass: {
15933 AllowOnePastEnd > 0);
15937 case Stmt::MemberExprClass: {
15941 case Stmt::CXXMemberCallExprClass: {
15945 case Stmt::ArraySectionExprClass: {
15951 nullptr, AllowOnePastEnd > 0);
15954 case Stmt::UnaryOperatorClass: {
15970 case Stmt::ConditionalOperatorClass: {
15972 if (
const Expr *lhs = cond->
getLHS())
15973 CheckArrayAccess(lhs);
15974 if (
const Expr *rhs = cond->
getRHS())
15975 CheckArrayAccess(rhs);
15978 case Stmt::CXXOperatorCallExprClass: {
15980 for (
const auto *Arg : OCE->arguments())
15981 CheckArrayAccess(Arg);
15991 Expr *RHS,
bool isProperty) {
16003 S.
Diag(Loc, diag::warn_arc_literal_assign)
16005 << (isProperty ? 0 : 1)
16013 Expr *RHS,
bool isProperty) {
16016 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16017 S.
Diag(Loc, diag::warn_arc_retained_assign)
16019 << (isProperty ? 0 : 1)
16023 RHS =
cast->getSubExpr();
16065 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16094 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16095 Diag(Loc, diag::warn_arc_retained_property_assign)
16099 RHS =
cast->getSubExpr();
16122 bool StmtLineInvalid;
16123 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16125 if (StmtLineInvalid)
16128 bool BodyLineInvalid;
16129 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16131 if (BodyLineInvalid)
16135 if (StmtLine != BodyLine)
16150 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16159 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16163 const Stmt *PossibleBody) {
16169 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16170 StmtLoc = FS->getRParenLoc();
16171 Body = FS->getBody();
16172 DiagID = diag::warn_empty_for_body;
16173 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16174 StmtLoc = WS->getRParenLoc();
16175 Body = WS->getBody();
16176 DiagID = diag::warn_empty_while_body;
16181 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16205 if (!ProbableTypo) {
16206 bool BodyColInvalid;
16207 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16209 if (BodyColInvalid)
16212 bool StmtColInvalid;
16215 if (StmtColInvalid)
16218 if (BodyCol > StmtCol)
16219 ProbableTypo =
true;
16222 if (ProbableTypo) {
16224 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16232 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16244 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16246 RHSExpr = CE->
getArg(0);
16247 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16248 CXXSCE && CXXSCE->isXValue())
16249 RHSExpr = CXXSCE->getSubExpr();
16253 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16254 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16257 if (LHSDeclRef && RHSDeclRef) {
16264 auto D =
Diag(OpLoc, diag::warn_self_move)
16280 const Expr *LHSBase = LHSExpr;
16281 const Expr *RHSBase = RHSExpr;
16282 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16283 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16284 if (!LHSME || !RHSME)
16287 while (LHSME && RHSME) {
16294 LHSME = dyn_cast<MemberExpr>(LHSBase);
16295 RHSME = dyn_cast<MemberExpr>(RHSBase);
16298 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16299 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16300 if (LHSDeclRef && RHSDeclRef) {
16307 Diag(OpLoc, diag::warn_self_move)
16314 Diag(OpLoc, diag::warn_self_move)
16338 bool AreUnionMembers =
false) {
16342 assert(((Field1Parent->isStructureOrClassType() &&
16343 Field2Parent->isStructureOrClassType()) ||
16344 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16345 "Can't evaluate layout compatibility between a struct field and a "
16347 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16348 (AreUnionMembers && Field1Parent->isUnionType())) &&
16349 "AreUnionMembers should be 'true' for union fields (only).");
16363 if (Bits1 != Bits2)
16367 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16368 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16371 if (!AreUnionMembers &&
16383 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16384 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16386 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16387 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16392 return isLayoutCompatible(C, F1, F2);
16403 for (
auto *Field1 : RD1->
fields()) {
16404 auto I = UnmatchedFields.begin();
16405 auto E = UnmatchedFields.end();
16407 for ( ; I != E; ++I) {
16409 bool Result = UnmatchedFields.erase(*I);
16419 return UnmatchedFields.empty();
16445 if (
C.hasSameType(T1, T2))
16454 if (TC1 == Type::Enum)
16456 if (TC1 == Type::Record) {
16475 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16506 const ValueDecl **VD, uint64_t *MagicValue,
16507 bool isConstantEvaluated) {
16515 case Stmt::UnaryOperatorClass: {
16524 case Stmt::DeclRefExprClass: {
16530 case Stmt::IntegerLiteralClass: {
16532 llvm::APInt MagicValueAPInt = IL->
getValue();
16533 if (MagicValueAPInt.getActiveBits() <= 64) {
16534 *MagicValue = MagicValueAPInt.getZExtValue();
16540 case Stmt::BinaryConditionalOperatorClass:
16541 case Stmt::ConditionalOperatorClass: {
16546 isConstantEvaluated)) {
16556 case Stmt::BinaryOperatorClass: {
16559 TypeExpr = BO->
getRHS();
16589 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16592 bool isConstantEvaluated) {
16593 FoundWrongKind =
false;
16598 uint64_t MagicValue;
16600 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16604 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16605 if (I->getArgumentKind() != ArgumentKind) {
16606 FoundWrongKind =
true;
16609 TypeInfo.Type = I->getMatchingCType();
16610 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16611 TypeInfo.MustBeNull = I->getMustBeNull();
16622 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16623 if (I == MagicValues->end())
16632 bool LayoutCompatible,
16634 if (!TypeTagForDatatypeMagicValues)
16635 TypeTagForDatatypeMagicValues.reset(
16636 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16639 (*TypeTagForDatatypeMagicValues)[Magic] =
16655 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16656 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16657 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16658 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16661void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16664 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16665 bool IsPointerAttr = Attr->getIsPointer();
16668 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16669 if (TypeTagIdxAST >= ExprArgs.size()) {
16670 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16671 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16674 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16675 bool FoundWrongKind;
16678 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16680 if (FoundWrongKind)
16682 diag::warn_type_tag_for_datatype_wrong_kind)
16688 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16689 if (ArgumentIdxAST >= ExprArgs.size()) {
16690 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16691 << 1 << Attr->getArgumentIdx().getSourceIndex();
16694 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16695 if (IsPointerAttr) {
16697 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16698 if (ICE->getType()->isVoidPointerType() &&
16699 ICE->getCastKind() == CK_BitCast)
16700 ArgumentExpr = ICE->getSubExpr();
16702 QualType ArgumentType = ArgumentExpr->
getType();
16708 if (TypeInfo.MustBeNull) {
16713 diag::warn_type_safety_null_pointer_required)
16721 QualType RequiredType = TypeInfo.Type;
16723 RequiredType =
Context.getPointerType(RequiredType);
16725 bool mismatch =
false;
16726 if (!TypeInfo.LayoutCompatible) {
16727 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16748 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16749 << ArgumentType << ArgumentKind
16750 << TypeInfo.LayoutCompatible << RequiredType
16768 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16776 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
16782 auto &MisalignedMembersForExpr =
16784 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16785 if (MA != MisalignedMembersForExpr.end() &&
16786 (T->isDependentType() || T->isIntegerType() ||
16787 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
16789 T->getPointeeType()) <= MA->Alignment))))
16790 MisalignedMembersForExpr.erase(MA);
16799 const auto *ME = dyn_cast<MemberExpr>(E);
16811 bool AnyIsPacked =
false;
16813 QualType BaseType = ME->getBase()->getType();
16814 if (BaseType->isDependentType())
16818 auto *RD = BaseType->castAsRecordDecl();
16823 auto *FD = dyn_cast<FieldDecl>(MD);
16829 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16830 ReverseMemberChain.push_back(FD);
16833 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16835 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16842 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16853 if (ExpectedAlignment.
isOne())
16858 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16859 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16863 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16867 if (DRE && !TopME->
isArrow()) {
16870 CompleteObjectAlignment =
16871 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16875 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16878 CompleteObjectAlignment < ExpectedAlignment) {
16889 for (
FieldDecl *FDI : ReverseMemberChain) {
16890 if (FDI->hasAttr<PackedAttr>() ||
16891 FDI->getParent()->hasAttr<PackedAttr>()) {
16893 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16899 assert(FD &&
"We did not find a packed FieldDecl!");
16900 Action(E, FD->
getParent(), FD, Alignment);
16904void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16905 using namespace std::placeholders;
16908 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16932bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16933 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16960 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16977 assert(!Args.empty() &&
"Should have at least one argument.");
16979 Expr *Arg0 = Args.front();
16982 auto EmitError = [&](
Expr *ArgI) {
16984 diag::err_typecheck_call_different_arg_types)
16985 << Arg0->
getType() << ArgI->getType();
16990 for (
Expr *ArgI : Args.drop_front())
17001 for (
Expr *ArgI : Args.drop_front()) {
17002 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17005 VecI->getElementType()) ||
17006 Vec0->getNumElements() != VecI->getNumElements()) {
17015std::optional<QualType>
17019 return std::nullopt;
17023 return std::nullopt;
17026 for (
int I = 0; I < 2; ++I) {
17030 return std::nullopt;
17031 Args[I] = Converted.
get();
17038 return std::nullopt;
17041 return std::nullopt;
17043 TheCall->
setArg(0, Args[0]);
17044 TheCall->
setArg(1, Args[1]);
17055 TheCall->
getArg(1), Loc) ||
17057 TheCall->
getArg(2), Loc))
17061 for (
int I = 0; I < 3; ++I) {
17066 Args[I] = Converted.
get();
17069 int ArgOrdinal = 1;
17070 for (
Expr *Arg : Args) {
17072 ArgTyRestr, ArgOrdinal++))
17079 for (
int I = 0; I < 3; ++I)
17080 TheCall->
setArg(I, Args[I]);
17086bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17098bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17107 diag::err_builtin_invalid_arg_type)
17108 << 1 << 2 << 1 << 1 << TyArg;
17122 Expr *Matrix = MatrixArg.
get();
17124 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17127 << 1 << 3 << 0 << 0
17134 QualType ResultType =
Context.getConstantMatrixType(
17135 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17138 TheCall->
setType(ResultType);
17141 TheCall->
setArg(0, Matrix);
17146static std::optional<unsigned>
17154 uint64_t
Dim =
Value->getZExtValue();
17170 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17172 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17180 unsigned PtrArgIdx = 0;
17181 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17182 Expr *RowsExpr = TheCall->
getArg(1);
17183 Expr *ColumnsExpr = TheCall->
getArg(2);
17184 Expr *StrideExpr = TheCall->
getArg(3);
17186 bool ArgError =
false;
17193 PtrExpr = PtrConv.
get();
17194 TheCall->
setArg(0, PtrExpr);
17201 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17202 QualType ElementTy;
17205 << PtrArgIdx + 1 << 0 << 5 << 0
17209 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17213 << PtrArgIdx + 1 << 0 << 5
17220 auto ApplyArgumentConversions = [
this](Expr *E) {
17229 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17231 RowsExpr = RowsConv.
get();
17232 TheCall->
setArg(1, RowsExpr);
17234 RowsExpr =
nullptr;
17236 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17238 ColumnsExpr = ColumnsConv.
get();
17239 TheCall->
setArg(2, ColumnsExpr);
17241 ColumnsExpr =
nullptr;
17252 std::optional<unsigned> MaybeRows;
17256 std::optional<unsigned> MaybeColumns;
17261 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17264 StrideExpr = StrideConv.
get();
17265 TheCall->
setArg(3, StrideExpr);
17268 if (std::optional<llvm::APSInt>
Value =
17271 if (Stride < *MaybeRows) {
17273 diag::err_builtin_matrix_stride_too_small);
17279 if (ArgError || !MaybeRows || !MaybeColumns)
17283 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17294 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17296 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17304 unsigned PtrArgIdx = 1;
17305 Expr *MatrixExpr = TheCall->
getArg(0);
17306 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17307 Expr *StrideExpr = TheCall->
getArg(2);
17309 bool ArgError =
false;
17315 MatrixExpr = MatrixConv.
get();
17316 TheCall->
setArg(0, MatrixExpr);
17323 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17326 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17334 PtrExpr = PtrConv.
get();
17335 TheCall->
setArg(1, PtrExpr);
17343 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17346 << PtrArgIdx + 1 << 0 << 5 << 0
17350 QualType ElementTy = PtrTy->getPointeeType();
17352 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17357 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17359 diag::err_builtin_matrix_pointer_arg_mismatch)
17360 << ElementTy << MatrixTy->getElementType();
17375 StrideExpr = StrideConv.
get();
17376 TheCall->
setArg(2, StrideExpr);
17381 if (std::optional<llvm::APSInt>
Value =
17384 if (Stride < MatrixTy->getNumRows()) {
17386 diag::err_builtin_matrix_stride_too_small);
17406 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17411 llvm::StringSet<> CalleeTCBs;
17412 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17413 CalleeTCBs.insert(A->getTCBName());
17414 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17415 CalleeTCBs.insert(A->getTCBName());
17419 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17420 StringRef CallerTCB = A->getTCBName();
17421 if (CalleeTCBs.count(CallerTCB) == 0) {
17422 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17423 << 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)
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 * getStart() const
StringRef toString() 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)
llvm::ImmutableSet< T > join(llvm::ImmutableSet< T > A, llvm::ImmutableSet< T > B, typename llvm::ImmutableSet< T >::Factory &F)
Computes the union of two ImmutableSets.
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.