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);
1510 Expr *Arg = TheCall->
getArg(0);
1518 llvm::APInt RawValue =
R.Val.getInt();
1519 llvm::APInt Mask(RawValue.getBitWidth(), 0777);
1520 llvm::APInt
Extra = RawValue & ~Mask;
1523 SmallString<16> ExtraStr;
1524 Extra.toString(ExtraStr, 8,
false);
1541 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1544 << DRE->getDecl()->getIdentifier();
1556 "__builtin_alloca has invalid address space");
1582enum PointerAuthOpKind {
1597 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1628 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1631 llvm::raw_svector_ostream Str(
Value);
1640 Result = KeyValue->getZExtValue();
1659 bool IsAddrDiscArg =
false;
1664 IsAddrDiscArg =
true;
1673 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1674 <<
Result->getExtValue();
1676 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1682 IntVal =
Result->getZExtValue();
1686static std::pair<const ValueDecl *, CharUnits>
1693 const auto *BaseDecl =
1698 return {BaseDecl,
Result.Val.getLValueOffset()};
1702 bool RequireConstant =
false) {
1710 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1711 return OpKind != PAO_BlendInteger;
1713 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1714 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1715 OpKind == PAO_SignGeneric;
1724 }
else if (AllowsInteger(OpKind) &&
1731 <<
unsigned(OpKind == PAO_Discriminator ? 1
1732 : OpKind == PAO_BlendPointer ? 2
1733 : OpKind == PAO_BlendInteger ? 3
1735 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1745 if (!RequireConstant) {
1747 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1750 ? diag::warn_ptrauth_sign_null_pointer
1751 : diag::warn_ptrauth_auth_null_pointer)
1761 if (OpKind == PAO_Sign) {
1779 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1784 assert(OpKind == PAO_Discriminator);
1790 if (
Call->getBuiltinCallee() ==
1791 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1806 assert(
Pointer->getType()->isPointerType());
1818 assert(
Integer->getType()->isIntegerType());
1824 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1837 Call->setType(
Call->getArgs()[0]->getType());
1868 PointerAuthOpKind OpKind,
1869 bool RequireConstant) {
1880 Call->setType(
Call->getArgs()[0]->getType());
1896 Call->setType(
Call->getArgs()[0]->getType());
1905 const Expr *AddendExpr =
Call->getArg(5);
1907 if (!AddendIsConstInt) {
1908 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
1922 Call->setType(
Call->getArgs()[0]->getType());
1931 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1934 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1935 if (!Literal || Literal->getCharByteWidth() != 1) {
1951 Call->setArg(0, FirstValue.
get());
1957 if (!FirstArgRecord) {
1958 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1959 << 0 << FirstArgType;
1964 diag::err_get_vtable_pointer_requires_complete_type)) {
1969 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1970 << 1 << FirstArgRecord;
1974 Call->setType(ReturnType);
1999 auto DiagSelect = [&]() -> std::optional<unsigned> {
2006 return std::optional<unsigned>{};
2021 diag::err_incomplete_type))
2025 "Unhandled non-object pointer case");
2053 if (PT->getPointeeType()->isFunctionType()) {
2055 diag::err_builtin_is_within_lifetime_invalid_arg)
2061 if (PT->getPointeeType()->isVariableArrayType()) {
2063 << 1 <<
"__builtin_is_within_lifetime";
2068 diag::err_builtin_is_within_lifetime_invalid_arg)
2082 diag::err_builtin_trivially_relocate_invalid_arg_type)
2089 diag::err_incomplete_type))
2093 T->isIncompleteArrayType()) {
2095 diag::err_builtin_trivially_relocate_invalid_arg_type)
2096 << (T.isConstQualified() ? 1 : 2);
2105 diag::err_builtin_trivially_relocate_invalid_arg_type)
2112 if (Size.isInvalid())
2116 if (Size.isInvalid())
2118 SizeExpr = Size.get();
2119 TheCall->
setArg(2, SizeExpr);
2129 llvm::Triple::ObjectFormatType CurObjFormat =
2131 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2144 llvm::Triple::ArchType CurArch =
2146 if (llvm::is_contained(SupportedArchs, CurArch))
2156bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2163 case llvm::Triple::arm:
2164 case llvm::Triple::armeb:
2165 case llvm::Triple::thumb:
2166 case llvm::Triple::thumbeb:
2168 case llvm::Triple::aarch64:
2169 case llvm::Triple::aarch64_32:
2170 case llvm::Triple::aarch64_be:
2172 case llvm::Triple::bpfeb:
2173 case llvm::Triple::bpfel:
2175 case llvm::Triple::dxil:
2177 case llvm::Triple::hexagon:
2179 case llvm::Triple::mips:
2180 case llvm::Triple::mipsel:
2181 case llvm::Triple::mips64:
2182 case llvm::Triple::mips64el:
2184 case llvm::Triple::spirv:
2185 case llvm::Triple::spirv32:
2186 case llvm::Triple::spirv64:
2187 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2190 case llvm::Triple::systemz:
2192 case llvm::Triple::x86:
2193 case llvm::Triple::x86_64:
2195 case llvm::Triple::ppc:
2196 case llvm::Triple::ppcle:
2197 case llvm::Triple::ppc64:
2198 case llvm::Triple::ppc64le:
2200 case llvm::Triple::amdgcn:
2202 case llvm::Triple::riscv32:
2203 case llvm::Triple::riscv64:
2204 case llvm::Triple::riscv32be:
2205 case llvm::Triple::riscv64be:
2207 case llvm::Triple::loongarch32:
2208 case llvm::Triple::loongarch64:
2211 case llvm::Triple::wasm32:
2212 case llvm::Triple::wasm64:
2214 case llvm::Triple::nvptx:
2215 case llvm::Triple::nvptx64:
2221 return T->isDependentType() ||
2222 (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
2237 switch (ArgTyRestr) {
2240 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2241 << ArgOrdinal << 2 << 1 << 1
2248 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2249 << ArgOrdinal << 5 << 0
2255 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2256 << ArgOrdinal << 5 << 1
2262 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2276 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2277 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2278 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2279 "Expecting __builtin_cpu_...");
2281 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2283 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2284 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2285 (!IsCPUSupports && TInfo->supportsCpuIs()));
2287 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2294 ? diag::err_builtin_aix_os_unsupported
2295 : diag::err_builtin_target_unsupported)
2301 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2339 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2340 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2341 BT->getNumBits() != 1) {
2343 << ArgTy << BT->getNumBits();
2419 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2422 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2431 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2432 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2452 TheCall->
setArg(0, Arg0);
2469 TheCall->
setArg(1, Arg1);
2475 << 2 << 1 << 4 << 0 << Arg1Ty;
2489 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2491 << (OnlyUnsigned ? 3 : 1)
2499 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2502 return OnlyUnsigned ? T->isUnsignedIntegerType() : T->isIntegerType();
2507 return emitError(S, Loc, T);
2512 return emitError(S, Loc, T);
2518 return emitError(S, Loc, T);
2523 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2528 return emitError(S, Loc, T);
2533 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2539 llvm_unreachable(
"conversion functions are permitted");
2558 TheCall->
setArg(0, Arg0);
2572 TheCall->
setArg(1, Arg1);
2583 unsigned Pos,
bool AllowConst,
2587 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2592 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2593 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2594 << Pos <<
"scalar pointer";
2603 diag::err_typecheck_convert_incompatible)
2612 bool TypeDependent =
false;
2613 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2641 Builtin::BI__builtin_masked_load))
2655 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2678 Builtin::BI__builtin_masked_store))
2686 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2697 << MaskTy << ValTy);
2701 PtrTy->getPointeeType().getUnqualifiedType()))
2703 diag::err_vec_builtin_incompatible_vector)
2732 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2745 << MaskTy << IdxTy);
2754 diag::err_vec_masked_load_store_ptr)
2783 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2798 << MaskTy << IdxTy);
2804 << MaskTy << ValTy);
2807 PtrTy->getPointeeType().getUnqualifiedType()))
2809 diag::err_vec_builtin_incompatible_vector)
2823 if (Args.size() == 0) {
2825 diag::err_typecheck_call_too_few_args_at_least)
2831 QualType FuncT = Args[0]->getType();
2834 if (Args.size() < 2) {
2836 diag::err_typecheck_call_too_few_args_at_least)
2842 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2843 QualType ObjectT = Args[1]->getType();
2845 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2894 tok::periodstar, ObjectArg.
get(), Args[0]);
2898 if (MPT->isMemberDataPointer())
2901 auto *MemCall =
new (S.
Context)
2925 return TyA->getElementType();
2932Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2937 unsigned ICEArguments = 0;
2939 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2944 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2946 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2951 if (ArgNo < TheCall->getNumArgs() &&
2954 ICEArguments &= ~(1 << ArgNo);
2958 switch (BuiltinID) {
2959 case Builtin::BI__builtin___get_unsafe_stack_start:
2960 case Builtin::BI__builtin___get_unsafe_stack_bottom:
2962 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
2963 <<
"__safestack_get_unsafe_stack_bottom";
2965 case Builtin::BI__builtin___get_unsafe_stack_top:
2967 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
2968 <<
"__safestack_get_unsafe_stack_top";
2970 case Builtin::BI__builtin___get_unsafe_stack_ptr:
2972 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
2973 <<
"__safestack_get_unsafe_stack_ptr";
2975 case Builtin::BI__builtin_cpu_supports:
2976 case Builtin::BI__builtin_cpu_is:
2978 Context.getAuxTargetInfo(), BuiltinID))
2981 case Builtin::BI__builtin_cpu_init:
2982 if (!
Context.getTargetInfo().supportsCpuInit()) {
2988 case Builtin::BI__builtin___CFStringMakeConstantString:
2992 *
this, BuiltinID, TheCall,
2993 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2996 "Wrong # arguments to builtin CFStringMakeConstantString");
2997 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
3000 case Builtin::BI__builtin_ms_va_start:
3001 case Builtin::BI__builtin_stdarg_start:
3002 case Builtin::BI__builtin_va_start:
3003 case Builtin::BI__builtin_c23_va_start:
3004 if (BuiltinVAStart(BuiltinID, TheCall))
3007 case Builtin::BI__va_start: {
3008 switch (
Context.getTargetInfo().getTriple().getArch()) {
3009 case llvm::Triple::aarch64:
3010 case llvm::Triple::arm:
3011 case llvm::Triple::thumb:
3012 if (BuiltinVAStartARMMicrosoft(TheCall))
3016 if (BuiltinVAStart(BuiltinID, TheCall))
3024 case Builtin::BI_interlockedbittestandset_acq:
3025 case Builtin::BI_interlockedbittestandset_rel:
3026 case Builtin::BI_interlockedbittestandset_nf:
3027 case Builtin::BI_interlockedbittestandreset_acq:
3028 case Builtin::BI_interlockedbittestandreset_rel:
3029 case Builtin::BI_interlockedbittestandreset_nf:
3032 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3037 case Builtin::BI_bittest64:
3038 case Builtin::BI_bittestandcomplement64:
3039 case Builtin::BI_bittestandreset64:
3040 case Builtin::BI_bittestandset64:
3041 case Builtin::BI_interlockedbittestandreset64:
3042 case Builtin::BI_interlockedbittestandset64:
3045 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3046 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
3051 case Builtin::BI_interlockedbittestandreset64_acq:
3052 case Builtin::BI_interlockedbittestandreset64_rel:
3053 case Builtin::BI_interlockedbittestandreset64_nf:
3054 case Builtin::BI_interlockedbittestandset64_acq:
3055 case Builtin::BI_interlockedbittestandset64_rel:
3056 case Builtin::BI_interlockedbittestandset64_nf:
3061 case Builtin::BI__builtin_set_flt_rounds:
3064 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3065 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
3066 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3067 llvm::Triple::ppc64le}))
3071 case Builtin::BI__builtin_isgreater:
3072 case Builtin::BI__builtin_isgreaterequal:
3073 case Builtin::BI__builtin_isless:
3074 case Builtin::BI__builtin_islessequal:
3075 case Builtin::BI__builtin_islessgreater:
3076 case Builtin::BI__builtin_isunordered:
3077 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3080 case Builtin::BI__builtin_fpclassify:
3081 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3084 case Builtin::BI__builtin_isfpclass:
3085 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3088 case Builtin::BI__builtin_isfinite:
3089 case Builtin::BI__builtin_isinf:
3090 case Builtin::BI__builtin_isinf_sign:
3091 case Builtin::BI__builtin_isnan:
3092 case Builtin::BI__builtin_issignaling:
3093 case Builtin::BI__builtin_isnormal:
3094 case Builtin::BI__builtin_issubnormal:
3095 case Builtin::BI__builtin_iszero:
3096 case Builtin::BI__builtin_signbit:
3097 case Builtin::BI__builtin_signbitf:
3098 case Builtin::BI__builtin_signbitl:
3099 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3102 case Builtin::BI__builtin_shufflevector:
3106 case Builtin::BI__builtin_masked_load:
3107 case Builtin::BI__builtin_masked_expand_load:
3109 case Builtin::BI__builtin_masked_store:
3110 case Builtin::BI__builtin_masked_compress_store:
3112 case Builtin::BI__builtin_masked_gather:
3114 case Builtin::BI__builtin_masked_scatter:
3116 case Builtin::BI__builtin_invoke:
3118 case Builtin::BI__builtin_prefetch:
3119 if (BuiltinPrefetch(TheCall))
3122 case Builtin::BI__builtin_alloca_with_align:
3123 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3124 if (BuiltinAllocaWithAlign(TheCall))
3127 case Builtin::BI__builtin_alloca:
3128 case Builtin::BI__builtin_alloca_uninitialized:
3135 case Builtin::BI__builtin_infer_alloc_token:
3139 case Builtin::BI__arithmetic_fence:
3140 if (BuiltinArithmeticFence(TheCall))
3143 case Builtin::BI__assume:
3144 case Builtin::BI__builtin_assume:
3145 if (BuiltinAssume(TheCall))
3148 case Builtin::BI__builtin_assume_aligned:
3149 if (BuiltinAssumeAligned(TheCall))
3152 case Builtin::BI__builtin_dynamic_object_size:
3153 case Builtin::BI__builtin_object_size:
3157 case Builtin::BI__builtin_longjmp:
3158 if (BuiltinLongjmp(TheCall))
3161 case Builtin::BI__builtin_setjmp:
3162 if (BuiltinSetjmp(TheCall))
3165 case Builtin::BI__builtin_complex:
3166 if (BuiltinComplex(TheCall))
3169 case Builtin::BI__builtin_classify_type:
3170 case Builtin::BI__builtin_constant_p: {
3179 case Builtin::BI__builtin_launder:
3181 case Builtin::BI__builtin_is_within_lifetime:
3183 case Builtin::BI__builtin_trivially_relocate:
3185 case Builtin::BI__builtin_clear_padding: {
3189 const Expr *PtrArg = TheCall->
getArg(0);
3190 const QualType PtrArgType = PtrArg->
getType();
3193 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3204 diag::err_typecheck_decl_incomplete_type))
3210 auto IsAddrOfDeclExpr = [&]() {
3212 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3213 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3217 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3218 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3222 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3223 if (!VarDecl || VarDecl->getType()->isReferenceType())
3228 QualType VarQType = VarDecl->getType();
3230 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3235 && !IsAddrOfDeclExpr()) {
3236 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3243 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3250 case Builtin::BI__sync_fetch_and_add:
3251 case Builtin::BI__sync_fetch_and_add_1:
3252 case Builtin::BI__sync_fetch_and_add_2:
3253 case Builtin::BI__sync_fetch_and_add_4:
3254 case Builtin::BI__sync_fetch_and_add_8:
3255 case Builtin::BI__sync_fetch_and_add_16:
3256 case Builtin::BI__sync_fetch_and_sub:
3257 case Builtin::BI__sync_fetch_and_sub_1:
3258 case Builtin::BI__sync_fetch_and_sub_2:
3259 case Builtin::BI__sync_fetch_and_sub_4:
3260 case Builtin::BI__sync_fetch_and_sub_8:
3261 case Builtin::BI__sync_fetch_and_sub_16:
3262 case Builtin::BI__sync_fetch_and_or:
3263 case Builtin::BI__sync_fetch_and_or_1:
3264 case Builtin::BI__sync_fetch_and_or_2:
3265 case Builtin::BI__sync_fetch_and_or_4:
3266 case Builtin::BI__sync_fetch_and_or_8:
3267 case Builtin::BI__sync_fetch_and_or_16:
3268 case Builtin::BI__sync_fetch_and_and:
3269 case Builtin::BI__sync_fetch_and_and_1:
3270 case Builtin::BI__sync_fetch_and_and_2:
3271 case Builtin::BI__sync_fetch_and_and_4:
3272 case Builtin::BI__sync_fetch_and_and_8:
3273 case Builtin::BI__sync_fetch_and_and_16:
3274 case Builtin::BI__sync_fetch_and_xor:
3275 case Builtin::BI__sync_fetch_and_xor_1:
3276 case Builtin::BI__sync_fetch_and_xor_2:
3277 case Builtin::BI__sync_fetch_and_xor_4:
3278 case Builtin::BI__sync_fetch_and_xor_8:
3279 case Builtin::BI__sync_fetch_and_xor_16:
3280 case Builtin::BI__sync_fetch_and_nand:
3281 case Builtin::BI__sync_fetch_and_nand_1:
3282 case Builtin::BI__sync_fetch_and_nand_2:
3283 case Builtin::BI__sync_fetch_and_nand_4:
3284 case Builtin::BI__sync_fetch_and_nand_8:
3285 case Builtin::BI__sync_fetch_and_nand_16:
3286 case Builtin::BI__sync_add_and_fetch:
3287 case Builtin::BI__sync_add_and_fetch_1:
3288 case Builtin::BI__sync_add_and_fetch_2:
3289 case Builtin::BI__sync_add_and_fetch_4:
3290 case Builtin::BI__sync_add_and_fetch_8:
3291 case Builtin::BI__sync_add_and_fetch_16:
3292 case Builtin::BI__sync_sub_and_fetch:
3293 case Builtin::BI__sync_sub_and_fetch_1:
3294 case Builtin::BI__sync_sub_and_fetch_2:
3295 case Builtin::BI__sync_sub_and_fetch_4:
3296 case Builtin::BI__sync_sub_and_fetch_8:
3297 case Builtin::BI__sync_sub_and_fetch_16:
3298 case Builtin::BI__sync_and_and_fetch:
3299 case Builtin::BI__sync_and_and_fetch_1:
3300 case Builtin::BI__sync_and_and_fetch_2:
3301 case Builtin::BI__sync_and_and_fetch_4:
3302 case Builtin::BI__sync_and_and_fetch_8:
3303 case Builtin::BI__sync_and_and_fetch_16:
3304 case Builtin::BI__sync_or_and_fetch:
3305 case Builtin::BI__sync_or_and_fetch_1:
3306 case Builtin::BI__sync_or_and_fetch_2:
3307 case Builtin::BI__sync_or_and_fetch_4:
3308 case Builtin::BI__sync_or_and_fetch_8:
3309 case Builtin::BI__sync_or_and_fetch_16:
3310 case Builtin::BI__sync_xor_and_fetch:
3311 case Builtin::BI__sync_xor_and_fetch_1:
3312 case Builtin::BI__sync_xor_and_fetch_2:
3313 case Builtin::BI__sync_xor_and_fetch_4:
3314 case Builtin::BI__sync_xor_and_fetch_8:
3315 case Builtin::BI__sync_xor_and_fetch_16:
3316 case Builtin::BI__sync_nand_and_fetch:
3317 case Builtin::BI__sync_nand_and_fetch_1:
3318 case Builtin::BI__sync_nand_and_fetch_2:
3319 case Builtin::BI__sync_nand_and_fetch_4:
3320 case Builtin::BI__sync_nand_and_fetch_8:
3321 case Builtin::BI__sync_nand_and_fetch_16:
3322 case Builtin::BI__sync_val_compare_and_swap:
3323 case Builtin::BI__sync_val_compare_and_swap_1:
3324 case Builtin::BI__sync_val_compare_and_swap_2:
3325 case Builtin::BI__sync_val_compare_and_swap_4:
3326 case Builtin::BI__sync_val_compare_and_swap_8:
3327 case Builtin::BI__sync_val_compare_and_swap_16:
3328 case Builtin::BI__sync_bool_compare_and_swap:
3329 case Builtin::BI__sync_bool_compare_and_swap_1:
3330 case Builtin::BI__sync_bool_compare_and_swap_2:
3331 case Builtin::BI__sync_bool_compare_and_swap_4:
3332 case Builtin::BI__sync_bool_compare_and_swap_8:
3333 case Builtin::BI__sync_bool_compare_and_swap_16:
3334 case Builtin::BI__sync_lock_test_and_set:
3335 case Builtin::BI__sync_lock_test_and_set_1:
3336 case Builtin::BI__sync_lock_test_and_set_2:
3337 case Builtin::BI__sync_lock_test_and_set_4:
3338 case Builtin::BI__sync_lock_test_and_set_8:
3339 case Builtin::BI__sync_lock_test_and_set_16:
3340 case Builtin::BI__sync_lock_release:
3341 case Builtin::BI__sync_lock_release_1:
3342 case Builtin::BI__sync_lock_release_2:
3343 case Builtin::BI__sync_lock_release_4:
3344 case Builtin::BI__sync_lock_release_8:
3345 case Builtin::BI__sync_lock_release_16:
3346 case Builtin::BI__sync_swap:
3347 case Builtin::BI__sync_swap_1:
3348 case Builtin::BI__sync_swap_2:
3349 case Builtin::BI__sync_swap_4:
3350 case Builtin::BI__sync_swap_8:
3351 case Builtin::BI__sync_swap_16:
3352 return BuiltinAtomicOverloaded(TheCallResult);
3353 case Builtin::BI__sync_synchronize:
3357 case Builtin::BI__builtin_nontemporal_load:
3358 case Builtin::BI__builtin_nontemporal_store:
3359 return BuiltinNontemporalOverloaded(TheCallResult);
3360 case Builtin::BI__builtin_memcpy_inline: {
3361 clang::Expr *SizeOp = TheCall->
getArg(2);
3373 case Builtin::BI__builtin_memset_inline: {
3374 clang::Expr *SizeOp = TheCall->
getArg(2);
3384#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3385 case Builtin::BI##ID: \
3386 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3387#include "clang/Basic/Builtins.inc"
3388 case Builtin::BI__annotation: {
3389 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3390 if (!TT.isOSWindows() && !TT.isUEFI()) {
3399 case Builtin::BI__builtin_annotation:
3403 case Builtin::BI__builtin_addressof:
3407 case Builtin::BI__builtin_function_start:
3411 case Builtin::BI__builtin_is_aligned:
3412 case Builtin::BI__builtin_align_up:
3413 case Builtin::BI__builtin_align_down:
3417 case Builtin::BI__builtin_add_overflow:
3418 case Builtin::BI__builtin_sub_overflow:
3419 case Builtin::BI__builtin_mul_overflow:
3423 case Builtin::BI__builtin_operator_new:
3424 case Builtin::BI__builtin_operator_delete: {
3425 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3427 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3430 case Builtin::BI__builtin_dump_struct:
3432 case Builtin::BI__builtin_expect_with_probability: {
3437 const Expr *ProbArg = TheCall->
getArg(2);
3438 SmallVector<PartialDiagnosticAt, 8> Notes;
3439 Expr::EvalResult Eval;
3443 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3450 bool LoseInfo =
false;
3451 Probability.convert(llvm::APFloat::IEEEdouble(),
3452 llvm::RoundingMode::Dynamic, &LoseInfo);
3453 if (!(Probability >= llvm::APFloat(0.0) &&
3454 Probability <= llvm::APFloat(1.0))) {
3461 case Builtin::BI__builtin_preserve_access_index:
3465 case Builtin::BI__builtin_call_with_static_chain:
3469 case Builtin::BI__exception_code:
3470 case Builtin::BI_exception_code:
3472 diag::err_seh___except_block))
3475 case Builtin::BI__exception_info:
3476 case Builtin::BI_exception_info:
3478 diag::err_seh___except_filter))
3481 case Builtin::BI__GetExceptionInfo:
3493 case Builtin::BIaddressof:
3494 case Builtin::BI__addressof:
3495 case Builtin::BIforward:
3496 case Builtin::BIforward_like:
3497 case Builtin::BImove:
3498 case Builtin::BImove_if_noexcept:
3499 case Builtin::BIas_const: {
3507 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3508 BuiltinID == Builtin::BI__addressof;
3510 (ReturnsPointer ?
Result->isAnyPointerType()
3511 :
Result->isReferenceType()) &&
3514 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3520 case Builtin::BI__builtin_ptrauth_strip:
3522 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3524 case Builtin::BI__builtin_ptrauth_sign_constant:
3527 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3530 case Builtin::BI__builtin_ptrauth_auth:
3533 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3535 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3537 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3539 case Builtin::BI__builtin_ptrauth_string_discriminator:
3542 case Builtin::BI__builtin_get_vtable_pointer:
3546 case Builtin::BIread_pipe:
3547 case Builtin::BIwrite_pipe:
3550 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3553 case Builtin::BIreserve_read_pipe:
3554 case Builtin::BIreserve_write_pipe:
3555 case Builtin::BIwork_group_reserve_read_pipe:
3556 case Builtin::BIwork_group_reserve_write_pipe:
3557 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3560 case Builtin::BIsub_group_reserve_read_pipe:
3561 case Builtin::BIsub_group_reserve_write_pipe:
3562 if (
OpenCL().checkSubgroupExt(TheCall) ||
3563 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3566 case Builtin::BIcommit_read_pipe:
3567 case Builtin::BIcommit_write_pipe:
3568 case Builtin::BIwork_group_commit_read_pipe:
3569 case Builtin::BIwork_group_commit_write_pipe:
3570 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3573 case Builtin::BIsub_group_commit_read_pipe:
3574 case Builtin::BIsub_group_commit_write_pipe:
3575 if (
OpenCL().checkSubgroupExt(TheCall) ||
3576 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3579 case Builtin::BIget_pipe_num_packets:
3580 case Builtin::BIget_pipe_max_packets:
3581 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3584 case Builtin::BIto_global:
3585 case Builtin::BIto_local:
3586 case Builtin::BIto_private:
3587 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3591 case Builtin::BIenqueue_kernel:
3592 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3595 case Builtin::BIget_kernel_work_group_size:
3596 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3597 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3600 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3601 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3602 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3605 case Builtin::BI__builtin_os_log_format:
3606 Cleanup.setExprNeedsCleanups(
true);
3608 case Builtin::BI__builtin_os_log_format_buffer_size:
3609 if (BuiltinOSLogFormat(TheCall))
3612 case Builtin::BI__builtin_frame_address:
3613 case Builtin::BI__builtin_return_address: {
3622 Result.Val.getInt() != 0)
3624 << ((BuiltinID == Builtin::BI__builtin_return_address)
3625 ?
"__builtin_return_address"
3626 :
"__builtin_frame_address")
3631 case Builtin::BI__builtin_nondeterministic_value: {
3632 if (BuiltinNonDeterministicValue(TheCall))
3639 case Builtin::BI__builtin_elementwise_abs:
3647 case Builtin::BI__builtin_elementwise_acos:
3648 case Builtin::BI__builtin_elementwise_asin:
3649 case Builtin::BI__builtin_elementwise_atan:
3650 case Builtin::BI__builtin_elementwise_ceil:
3651 case Builtin::BI__builtin_elementwise_cos:
3652 case Builtin::BI__builtin_elementwise_cosh:
3653 case Builtin::BI__builtin_elementwise_exp:
3654 case Builtin::BI__builtin_elementwise_exp2:
3655 case Builtin::BI__builtin_elementwise_exp10:
3656 case Builtin::BI__builtin_elementwise_floor:
3657 case Builtin::BI__builtin_elementwise_log:
3658 case Builtin::BI__builtin_elementwise_log2:
3659 case Builtin::BI__builtin_elementwise_log10:
3660 case Builtin::BI__builtin_elementwise_roundeven:
3661 case Builtin::BI__builtin_elementwise_round:
3662 case Builtin::BI__builtin_elementwise_rint:
3663 case Builtin::BI__builtin_elementwise_nearbyint:
3664 case Builtin::BI__builtin_elementwise_sin:
3665 case Builtin::BI__builtin_elementwise_sinh:
3666 case Builtin::BI__builtin_elementwise_sqrt:
3667 case Builtin::BI__builtin_elementwise_tan:
3668 case Builtin::BI__builtin_elementwise_tanh:
3669 case Builtin::BI__builtin_elementwise_trunc:
3670 case Builtin::BI__builtin_elementwise_canonicalize:
3675 case Builtin::BI__builtin_elementwise_fma:
3680 case Builtin::BI__builtin_elementwise_ldexp: {
3702 const auto *Vec0 = TyA->
getAs<VectorType>();
3703 const auto *Vec1 = TyExp->
getAs<VectorType>();
3704 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3706 if (Arg0Length != Arg1Length) {
3708 diag::err_typecheck_vector_lengths_not_equal)
3722 case Builtin::BI__builtin_elementwise_minnum:
3723 case Builtin::BI__builtin_elementwise_maxnum:
3724 case Builtin::BI__builtin_elementwise_minimum:
3725 case Builtin::BI__builtin_elementwise_maximum:
3726 case Builtin::BI__builtin_elementwise_minimumnum:
3727 case Builtin::BI__builtin_elementwise_maximumnum:
3728 case Builtin::BI__builtin_elementwise_atan2:
3729 case Builtin::BI__builtin_elementwise_fmod:
3730 case Builtin::BI__builtin_elementwise_pow:
3731 if (BuiltinElementwiseMath(TheCall,
3737 case Builtin::BI__builtin_elementwise_add_sat:
3738 case Builtin::BI__builtin_elementwise_sub_sat:
3739 case Builtin::BI__builtin_elementwise_clmul:
3740 case Builtin::BI__builtin_elementwise_pext:
3741 case Builtin::BI__builtin_elementwise_pdep:
3742 if (BuiltinElementwiseMath(TheCall,
3746 case Builtin::BI__builtin_elementwise_fshl:
3747 case Builtin::BI__builtin_elementwise_fshr:
3752 case Builtin::BI__builtin_elementwise_min:
3753 case Builtin::BI__builtin_elementwise_max: {
3754 if (BuiltinElementwiseMath(TheCall))
3756 Expr *Arg0 = TheCall->
getArg(0);
3757 Expr *Arg1 = TheCall->
getArg(1);
3758 QualType Ty0 = Arg0->
getType();
3759 QualType Ty1 = Arg1->
getType();
3760 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3761 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3764 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3765 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3766 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3769 case Builtin::BI__builtin_elementwise_popcount:
3770 case Builtin::BI__builtin_elementwise_bitreverse:
3775 case Builtin::BI__builtin_elementwise_copysign: {
3784 QualType MagnitudeTy = Magnitude.
get()->
getType();
3797 diag::err_typecheck_call_different_arg_types)
3798 << MagnitudeTy << SignTy;
3806 case Builtin::BI__builtin_elementwise_clzg:
3807 case Builtin::BI__builtin_elementwise_ctzg:
3815 }
else if (BuiltinElementwiseMath(
3819 case Builtin::BI__builtin_reduce_max:
3820 case Builtin::BI__builtin_reduce_min: {
3821 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3824 const Expr *Arg = TheCall->
getArg(0);
3829 ElTy = TyA->getElementType();
3833 if (ElTy.isNull()) {
3843 case Builtin::BI__builtin_reduce_maximum:
3844 case Builtin::BI__builtin_reduce_minimum: {
3845 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3848 const Expr *Arg = TheCall->
getArg(0);
3853 ElTy = TyA->getElementType();
3857 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3870 case Builtin::BI__builtin_reduce_add:
3871 case Builtin::BI__builtin_reduce_mul:
3872 case Builtin::BI__builtin_reduce_xor:
3873 case Builtin::BI__builtin_reduce_or:
3874 case Builtin::BI__builtin_reduce_and: {
3875 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3878 const Expr *Arg = TheCall->
getArg(0);
3892 case Builtin::BI__builtin_reduce_assoc_fadd:
3893 case Builtin::BI__builtin_reduce_in_order_fadd: {
3895 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
3920 diag::err_builtin_invalid_arg_type)
3932 case Builtin::BI__builtin_matrix_transpose:
3933 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3935 case Builtin::BI__builtin_matrix_column_major_load:
3936 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3938 case Builtin::BI__builtin_matrix_column_major_store:
3939 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3941 case Builtin::BI__builtin_verbose_trap:
3946 case Builtin::BI__builtin_get_device_side_mangled_name: {
3947 auto Check = [](CallExpr *TheCall) {
3953 auto *D = DRE->getDecl();
3956 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3957 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3959 if (!Check(TheCall)) {
3961 diag::err_hip_invalid_args_builtin_mangled_name);
3966 case Builtin::BI__builtin_bswapg:
3970 case Builtin::BI__builtin_bitreverseg:
3974 case Builtin::BI__builtin_popcountg:
3978 case Builtin::BI__builtin_clzg:
3979 case Builtin::BI__builtin_ctzg:
3984 case Builtin::BI__builtin_stdc_rotate_left:
3985 case Builtin::BI__builtin_stdc_rotate_right:
3990 case Builtin::BI__builtin_stdc_memreverse8:
3991 case Builtin::BIstdc_memreverse8:
3992 case Builtin::BIstdc_memreverse8u8:
3993 case Builtin::BIstdc_memreverse8u16:
3994 case Builtin::BIstdc_memreverse8u32:
3995 case Builtin::BIstdc_memreverse8u64:
3996 if (
Context.getTargetInfo().getCharWidth() != 8) {
4003 case Builtin::BI__builtin_stdc_bit_floor:
4004 case Builtin::BI__builtin_stdc_bit_ceil:
4008 case Builtin::BI__builtin_stdc_has_single_bit:
4012 case Builtin::BI__builtin_stdc_leading_zeros:
4013 case Builtin::BI__builtin_stdc_leading_ones:
4014 case Builtin::BI__builtin_stdc_trailing_zeros:
4015 case Builtin::BI__builtin_stdc_trailing_ones:
4016 case Builtin::BI__builtin_stdc_first_leading_zero:
4017 case Builtin::BI__builtin_stdc_first_leading_one:
4018 case Builtin::BI__builtin_stdc_first_trailing_zero:
4019 case Builtin::BI__builtin_stdc_first_trailing_one:
4020 case Builtin::BI__builtin_stdc_count_zeros:
4021 case Builtin::BI__builtin_stdc_count_ones:
4022 case Builtin::BI__builtin_stdc_bit_width:
4027 case Builtin::BI__builtin_allow_runtime_check: {
4028 Expr *Arg = TheCall->
getArg(0);
4038 case Builtin::BI__builtin_allow_sanitize_check: {
4042 Expr *Arg = TheCall->
getArg(0);
4044 const StringLiteral *SanitizerName =
4046 if (!SanitizerName) {
4052 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4053 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4054 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4058 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4064 case Builtin::BI__builtin_counted_by_ref:
4065 if (BuiltinCountedByRef(TheCall))
4075 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4076 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4077 assert(
Context.getAuxTargetInfo() &&
4078 "Aux Target Builtin, but not an aux target?");
4080 if (CheckTSBuiltinFunctionCall(
4082 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4085 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4091 return TheCallResult;
4106 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4110 diag::err_argument_not_contiguous_bit_field)
4117 bool IsVariadic =
false;
4120 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4121 IsVariadic = BD->isVariadic();
4122 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4123 IsVariadic = OMD->isVariadic();
4130 bool HasImplicitThisParam,
bool IsVariadic,
4134 else if (IsVariadic)
4144 if (HasImplicitThisParam) {
4176 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4177 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4178 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4179 Expr = ILE->getInit(0);
4189 const Expr *ArgExpr,
4193 S.
PDiag(diag::warn_null_arg)
4199 if (
auto nullability =
type->getNullability())
4210 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4216 llvm::SmallBitVector NonNullArgs;
4222 for (
const auto *Arg : Args)
4229 unsigned IdxAST = Idx.getASTIndex();
4230 if (IdxAST >= Args.size())
4232 if (NonNullArgs.empty())
4233 NonNullArgs.resize(Args.size());
4234 NonNullArgs.set(IdxAST);
4243 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4248 unsigned ParamIndex = 0;
4250 I != E; ++I, ++ParamIndex) {
4253 if (NonNullArgs.empty())
4254 NonNullArgs.resize(Args.size());
4256 NonNullArgs.set(ParamIndex);
4263 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4268 type = blockType->getPointeeType();
4282 if (NonNullArgs.empty())
4283 NonNullArgs.resize(Args.size());
4285 NonNullArgs.set(Index);
4294 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4295 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4296 if (NonNullArgs[ArgIndex])
4302 StringRef ParamName,
QualType ArgTy,
4325 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4326 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4330 if (ArgAlign < ParamAlign)
4331 Diag(Loc, diag::warn_param_mismatched_alignment)
4333 << ParamName << (FDecl !=
nullptr) << FDecl;
4337 const Expr *ThisArg,
4339 if (!FD || Args.empty())
4341 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4342 if (Idx == LifetimeCaptureByAttr::Global ||
4343 Idx == LifetimeCaptureByAttr::Unknown)
4345 if (IsMemberFunction && Idx == 0)
4347 return Args[Idx - IsMemberFunction];
4349 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4354 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4355 for (
int CapturingParamIdx :
Attr->params()) {
4356 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4360 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4363 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4371 I + IsMemberFunction);
4373 if (IsMemberFunction) {
4381 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4391 llvm::any_of(Args, [](
const Expr *E) {
4392 return E && E->isInstantiationDependent();
4397 llvm::SmallBitVector CheckedVarArgs;
4399 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4401 CheckedVarArgs.resize(Args.size());
4402 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4407 CheckedVarArgs.resize(Args.size());
4408 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4415 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4419 : isa_and_nonnull<FunctionDecl>(FDecl)
4421 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4425 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4427 if (
const Expr *Arg = Args[ArgIdx]) {
4428 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4435 if (FDecl || Proto) {
4440 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4441 CheckArgumentWithTypeTag(I, Args, Loc);
4447 if (!Proto && FDecl) {
4449 if (isa_and_nonnull<FunctionProtoType>(FT))
4455 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4457 bool IsScalableArg =
false;
4458 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4460 if (
const Expr *Arg = Args[ArgIdx]) {
4464 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4472 IsScalableArg =
true;
4474 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4483 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4484 llvm::StringMap<bool> CallerFeatureMap;
4485 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4486 if (!CallerFeatureMap.contains(
"sme"))
4487 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4488 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4489 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4498 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4500 (IsScalableArg || IsScalableRet)) {
4501 bool IsCalleeStreaming =
4503 bool IsCalleeStreamingCompatible =
4507 if (!IsCalleeStreamingCompatible &&
4511 unsigned VL = LO.VScaleMin * 128;
4512 unsigned SVL = LO.VScaleStreamingMin * 128;
4513 bool IsVLMismatch = VL && SVL && VL != SVL;
4515 auto EmitDiag = [&](
bool IsArg) {
4519 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4520 << IsArg << IsCalleeStreaming << SVL << VL;
4523 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4524 << IsArg << SVL << VL;
4526 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4543 bool CallerHasZAState =
false;
4544 bool CallerHasZT0State =
false;
4546 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4548 CallerHasZAState =
true;
4550 CallerHasZT0State =
true;
4554 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4556 CallerHasZT0State |=
4558 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4564 Diag(Loc, diag::err_sme_za_call_no_za_state);
4567 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4571 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4572 Diag(Loc, diag::note_sme_use_preserves_za);
4577 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4578 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4579 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4580 if (!Arg->isValueDependent()) {
4582 if (Arg->EvaluateAsInt(Align,
Context)) {
4583 const llvm::APSInt &I = Align.
Val.
getInt();
4584 if (!I.isPowerOf2())
4585 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4586 << Arg->getSourceRange();
4589 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4598 << diag::OffloadLang::SYCL;
4620 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4621 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4623 checkCall(FDecl, Proto,
nullptr, Args,
true,
4632 IsMemberOperatorCall;
4638 Expr *ImplicitThis =
nullptr;
4643 ImplicitThis = Args[0];
4646 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4657 ThisType =
Context.getPointerType(ThisType);
4663 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4681 CheckAbsoluteValueFunction(TheCall, FDecl);
4682 CheckMaxUnsignedZero(TheCall, FDecl);
4683 CheckInfNaNFunction(TheCall, FDecl);
4694 case Builtin::BIstrlcpy:
4695 case Builtin::BIstrlcat:
4696 CheckStrlcpycatArguments(TheCall, FnInfo);
4698 case Builtin::BIstrncat:
4699 CheckStrncatArguments(TheCall, FnInfo);
4701 case Builtin::BIfree:
4702 CheckFreeArguments(TheCall);
4705 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4714 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4715 Ty =
V->getType().getNonReferenceType();
4716 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4717 Ty = F->getType().getNonReferenceType();
4754 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4757 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4759 case AtomicExpr::AO__c11_atomic_init:
4760 case AtomicExpr::AO__opencl_atomic_init:
4761 llvm_unreachable(
"There is no ordering argument for an init");
4763 case AtomicExpr::AO__c11_atomic_load:
4764 case AtomicExpr::AO__opencl_atomic_load:
4765 case AtomicExpr::AO__hip_atomic_load:
4766 case AtomicExpr::AO__atomic_load_n:
4767 case AtomicExpr::AO__atomic_load:
4768 case AtomicExpr::AO__scoped_atomic_load_n:
4769 case AtomicExpr::AO__scoped_atomic_load:
4770 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4771 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4773 case AtomicExpr::AO__c11_atomic_store:
4774 case AtomicExpr::AO__opencl_atomic_store:
4775 case AtomicExpr::AO__hip_atomic_store:
4776 case AtomicExpr::AO__atomic_store:
4777 case AtomicExpr::AO__atomic_store_n:
4778 case AtomicExpr::AO__scoped_atomic_store:
4779 case AtomicExpr::AO__scoped_atomic_store_n:
4780 case AtomicExpr::AO__atomic_clear:
4781 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4782 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4783 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4813#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4814 case AtomicExpr::AO__hip_atomic_##hip: \
4815 OldName = "__hip_atomic_" #hip; \
4816 NewName = "__scoped_atomic_" #scoped; \
4829#undef HIP_ATOMIC_FIXABLE
4830 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4831 OldName =
"__hip_atomic_compare_exchange_weak";
4832 NewName =
"__scoped_atomic_compare_exchange";
4835 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4836 OldName =
"__hip_atomic_compare_exchange_strong";
4837 NewName =
"__scoped_atomic_compare_exchange";
4841 llvm_unreachable(
"unhandled HIP atomic op");
4844 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4845 << OldName << NewName;
4852 std::optional<llvm::APSInt> ScopeVal =
4857 StringRef ScopeName;
4858 switch (ScopeVal->getZExtValue()) {
4860 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4863 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4866 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4869 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4872 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
4875 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
4927 const unsigned NumForm = ClearByte + 1;
4928 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4929 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4937 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4938 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4939 "need to update code for modified forms");
4940 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4941 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4942 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4943 "need to update code for modified C11 atomics");
4944 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4945 Op <= AtomicExpr::AO__opencl_atomic_store;
4946 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4947 Op <= AtomicExpr::AO__hip_atomic_store;
4948 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4949 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4950 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4951 Op <= AtomicExpr::AO__c11_atomic_store) ||
4953 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4954 Op == AtomicExpr::AO__atomic_store_n ||
4955 Op == AtomicExpr::AO__atomic_exchange_n ||
4956 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4957 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4958 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4959 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4960 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4964 enum ArithOpExtraValueType {
4970 unsigned ArithAllows = AOEVT_None;
4973 case AtomicExpr::AO__c11_atomic_init:
4974 case AtomicExpr::AO__opencl_atomic_init:
4978 case AtomicExpr::AO__c11_atomic_load:
4979 case AtomicExpr::AO__opencl_atomic_load:
4980 case AtomicExpr::AO__hip_atomic_load:
4981 case AtomicExpr::AO__atomic_load_n:
4982 case AtomicExpr::AO__scoped_atomic_load_n:
4983 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4987 case AtomicExpr::AO__atomic_load:
4988 case AtomicExpr::AO__scoped_atomic_load:
4989 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4993 case AtomicExpr::AO__c11_atomic_store:
4994 case AtomicExpr::AO__opencl_atomic_store:
4995 case AtomicExpr::AO__hip_atomic_store:
4996 case AtomicExpr::AO__atomic_store:
4997 case AtomicExpr::AO__atomic_store_n:
4998 case AtomicExpr::AO__scoped_atomic_store:
4999 case AtomicExpr::AO__scoped_atomic_store_n:
5000 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5003 case AtomicExpr::AO__atomic_fetch_add:
5004 case AtomicExpr::AO__atomic_fetch_sub:
5005 case AtomicExpr::AO__atomic_add_fetch:
5006 case AtomicExpr::AO__atomic_sub_fetch:
5007 case AtomicExpr::AO__scoped_atomic_fetch_add:
5008 case AtomicExpr::AO__scoped_atomic_fetch_sub:
5009 case AtomicExpr::AO__scoped_atomic_add_fetch:
5010 case AtomicExpr::AO__scoped_atomic_sub_fetch:
5011 case AtomicExpr::AO__c11_atomic_fetch_add:
5012 case AtomicExpr::AO__c11_atomic_fetch_sub:
5013 case AtomicExpr::AO__opencl_atomic_fetch_add:
5014 case AtomicExpr::AO__opencl_atomic_fetch_sub:
5015 case AtomicExpr::AO__hip_atomic_fetch_add:
5016 case AtomicExpr::AO__hip_atomic_fetch_sub:
5017 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5020 case AtomicExpr::AO__atomic_fetch_fminimum:
5021 case AtomicExpr::AO__atomic_fetch_fmaximum:
5022 case AtomicExpr::AO__atomic_fetch_fminimum_num:
5023 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
5024 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
5025 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
5026 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
5027 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
5028 ArithAllows = AOEVT_FP;
5031 case AtomicExpr::AO__atomic_fetch_max:
5032 case AtomicExpr::AO__atomic_fetch_min:
5033 case AtomicExpr::AO__atomic_max_fetch:
5034 case AtomicExpr::AO__atomic_min_fetch:
5035 case AtomicExpr::AO__scoped_atomic_fetch_max:
5036 case AtomicExpr::AO__scoped_atomic_fetch_min:
5037 case AtomicExpr::AO__scoped_atomic_max_fetch:
5038 case AtomicExpr::AO__scoped_atomic_min_fetch:
5039 case AtomicExpr::AO__c11_atomic_fetch_max:
5040 case AtomicExpr::AO__c11_atomic_fetch_min:
5041 case AtomicExpr::AO__opencl_atomic_fetch_max:
5042 case AtomicExpr::AO__opencl_atomic_fetch_min:
5043 case AtomicExpr::AO__hip_atomic_fetch_max:
5044 case AtomicExpr::AO__hip_atomic_fetch_min:
5045 ArithAllows = AOEVT_Int | AOEVT_FP;
5048 case AtomicExpr::AO__c11_atomic_fetch_and:
5049 case AtomicExpr::AO__c11_atomic_fetch_or:
5050 case AtomicExpr::AO__c11_atomic_fetch_xor:
5051 case AtomicExpr::AO__hip_atomic_fetch_and:
5052 case AtomicExpr::AO__hip_atomic_fetch_or:
5053 case AtomicExpr::AO__hip_atomic_fetch_xor:
5054 case AtomicExpr::AO__c11_atomic_fetch_nand:
5055 case AtomicExpr::AO__opencl_atomic_fetch_and:
5056 case AtomicExpr::AO__opencl_atomic_fetch_or:
5057 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5058 case AtomicExpr::AO__atomic_fetch_and:
5059 case AtomicExpr::AO__atomic_fetch_or:
5060 case AtomicExpr::AO__atomic_fetch_xor:
5061 case AtomicExpr::AO__atomic_fetch_nand:
5062 case AtomicExpr::AO__atomic_and_fetch:
5063 case AtomicExpr::AO__atomic_or_fetch:
5064 case AtomicExpr::AO__atomic_xor_fetch:
5065 case AtomicExpr::AO__atomic_nand_fetch:
5066 case AtomicExpr::AO__atomic_fetch_uinc:
5067 case AtomicExpr::AO__atomic_fetch_udec:
5068 case AtomicExpr::AO__scoped_atomic_fetch_and:
5069 case AtomicExpr::AO__scoped_atomic_fetch_or:
5070 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5071 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5072 case AtomicExpr::AO__scoped_atomic_and_fetch:
5073 case AtomicExpr::AO__scoped_atomic_or_fetch:
5074 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5075 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5076 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5077 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5081 case AtomicExpr::AO__c11_atomic_exchange:
5082 case AtomicExpr::AO__hip_atomic_exchange:
5083 case AtomicExpr::AO__opencl_atomic_exchange:
5084 case AtomicExpr::AO__atomic_exchange_n:
5085 case AtomicExpr::AO__scoped_atomic_exchange_n:
5086 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5090 case AtomicExpr::AO__atomic_exchange:
5091 case AtomicExpr::AO__scoped_atomic_exchange:
5092 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5096 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5097 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5098 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5099 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5100 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5101 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5105 case AtomicExpr::AO__atomic_compare_exchange:
5106 case AtomicExpr::AO__atomic_compare_exchange_n:
5107 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5108 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5109 ArithAllows = AOEVT_Pointer;
5113 case AtomicExpr::AO__atomic_test_and_set:
5114 Form = TestAndSetByte;
5117 case AtomicExpr::AO__atomic_clear:
5122 unsigned AdjustedNumArgs = NumArgs[Form];
5123 if ((IsOpenCL || IsHIP || IsScoped) &&
5124 Op != AtomicExpr::AO__opencl_atomic_init)
5127 if (Args.size() < AdjustedNumArgs) {
5128 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5129 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5132 }
else if (Args.size() > AdjustedNumArgs) {
5133 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5134 diag::err_typecheck_call_too_many_args)
5135 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5141 Expr *Ptr = Args[0];
5146 Ptr = ConvertedPtr.
get();
5149 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5159 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5165 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5171 }
else if (Form != Load && Form != LoadCopy) {
5173 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5179 if (Form != TestAndSetByte && Form != ClearByte) {
5182 diag::err_incomplete_type))
5185 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5186 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5196 pointerType->getPointeeType().getCVRQualifiers());
5206 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5216 auto IsAllowedValueType = [&](
QualType ValType,
5217 unsigned AllowedType) ->
bool {
5218 bool IsX87LongDouble =
5220 &
Context.getTargetInfo().getLongDoubleFormat() ==
5221 &llvm::APFloat::x87DoubleExtended();
5225 return (AllowedType & AOEVT_Int) || AllowedType != AOEVT_FP;
5227 return AllowedType & AOEVT_Pointer;
5231 if (IsX87LongDouble)
5235 if (!IsAllowedValueType(ValType, ArithAllows)) {
5237 ArithAllows == AOEVT_FP
5238 ? diag::err_atomic_op_needs_atomic_fp
5239 : (ArithAllows & AOEVT_FP
5240 ? (ArithAllows & AOEVT_Pointer
5241 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5242 : diag::err_atomic_op_needs_atomic_int_or_fp)
5243 : (ArithAllows & AOEVT_Pointer
5244 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5245 : diag::err_atomic_op_needs_atomic_int));
5252 diag::err_incomplete_type)) {
5263 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5279 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5291 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5294 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5300 bool IsPassedByAddress =
false;
5301 if (!IsC11 && !IsHIP && !IsN) {
5303 IsPassedByAddress =
true;
5308 APIOrderedArgs.push_back(Args[0]);
5312 APIOrderedArgs.push_back(Args[1]);
5318 APIOrderedArgs.push_back(Args[2]);
5319 APIOrderedArgs.push_back(Args[1]);
5322 APIOrderedArgs.push_back(Args[2]);
5323 APIOrderedArgs.push_back(Args[3]);
5324 APIOrderedArgs.push_back(Args[1]);
5327 APIOrderedArgs.push_back(Args[2]);
5328 APIOrderedArgs.push_back(Args[4]);
5329 APIOrderedArgs.push_back(Args[1]);
5330 APIOrderedArgs.push_back(Args[3]);
5333 APIOrderedArgs.push_back(Args[2]);
5334 APIOrderedArgs.push_back(Args[4]);
5335 APIOrderedArgs.push_back(Args[5]);
5336 APIOrderedArgs.push_back(Args[1]);
5337 APIOrderedArgs.push_back(Args[3]);
5339 case TestAndSetByte:
5341 APIOrderedArgs.push_back(Args[1]);
5345 APIOrderedArgs.append(Args.begin(), Args.end());
5352 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5354 if (i < NumVals[Form] + 1) {
5367 assert(Form != Load);
5369 Ty =
Context.getPointerDiffType();
5372 else if (Form ==
Copy || Form == Xchg) {
5373 if (IsPassedByAddress) {
5380 Expr *ValArg = APIOrderedArgs[i];
5387 AS = PtrTy->getPointeeType().getAddressSpace();
5396 if (IsPassedByAddress)
5416 APIOrderedArgs[i] = Arg.
get();
5421 SubExprs.push_back(Ptr);
5425 SubExprs.push_back(APIOrderedArgs[1]);
5428 case TestAndSetByte:
5430 SubExprs.push_back(APIOrderedArgs[1]);
5436 SubExprs.push_back(APIOrderedArgs[2]);
5437 SubExprs.push_back(APIOrderedArgs[1]);
5441 SubExprs.push_back(APIOrderedArgs[3]);
5442 SubExprs.push_back(APIOrderedArgs[1]);
5443 SubExprs.push_back(APIOrderedArgs[2]);
5446 SubExprs.push_back(APIOrderedArgs[3]);
5447 SubExprs.push_back(APIOrderedArgs[1]);
5448 SubExprs.push_back(APIOrderedArgs[4]);
5449 SubExprs.push_back(APIOrderedArgs[2]);
5452 SubExprs.push_back(APIOrderedArgs[4]);
5453 SubExprs.push_back(APIOrderedArgs[1]);
5454 SubExprs.push_back(APIOrderedArgs[5]);
5455 SubExprs.push_back(APIOrderedArgs[2]);
5456 SubExprs.push_back(APIOrderedArgs[3]);
5461 if (SubExprs.size() >= 2 && Form !=
Init) {
5462 std::optional<llvm::APSInt>
Success =
5463 SubExprs[1]->getIntegerConstantExpr(
Context);
5465 Diag(SubExprs[1]->getBeginLoc(),
5466 diag::warn_atomic_op_has_invalid_memory_order)
5467 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5468 << SubExprs[1]->getSourceRange();
5470 if (SubExprs.size() >= 5) {
5471 if (std::optional<llvm::APSInt>
Failure =
5472 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5473 if (!llvm::is_contained(
5474 {llvm::AtomicOrderingCABI::relaxed,
5475 llvm::AtomicOrderingCABI::consume,
5476 llvm::AtomicOrderingCABI::acquire,
5477 llvm::AtomicOrderingCABI::seq_cst},
5478 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5479 Diag(SubExprs[3]->getBeginLoc(),
5480 diag::warn_atomic_op_has_invalid_memory_order)
5481 << 2 << SubExprs[3]->getSourceRange();
5488 auto *
Scope = Args[Args.size() - 1];
5489 if (std::optional<llvm::APSInt>
Result =
5491 if (!ScopeModel->isValid(
Result->getZExtValue()))
5492 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5493 <<
Scope->getSourceRange();
5495 SubExprs.push_back(
Scope);
5504 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5505 Op == AtomicExpr::AO__c11_atomic_store ||
5506 Op == AtomicExpr::AO__opencl_atomic_load ||
5507 Op == AtomicExpr::AO__hip_atomic_load ||
5508 Op == AtomicExpr::AO__opencl_atomic_store ||
5509 Op == AtomicExpr::AO__hip_atomic_store) &&
5510 Context.AtomicUsesUnsupportedLibcall(AE))
5512 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5513 Op == AtomicExpr::AO__opencl_atomic_load ||
5514 Op == AtomicExpr::AO__hip_atomic_load)
5519 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5535 assert(Fn &&
"builtin call without direct callee!");
5551 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5558 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5560 <<
Callee->getSourceRange();
5569 Expr *FirstArg = TheCall->
getArg(0);
5573 FirstArg = FirstArgResult.
get();
5574 TheCall->
setArg(0, FirstArg);
5586 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5593 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5623 QualType ResultType = ValType;
5628#define BUILTIN_ROW(x) \
5629 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5630 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5632 static const unsigned BuiltinIndices[][5] = {
5657 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5658 case 1: SizeIndex = 0;
break;
5659 case 2: SizeIndex = 1;
break;
5660 case 4: SizeIndex = 2;
break;
5661 case 8: SizeIndex = 3;
break;
5662 case 16: SizeIndex = 4;
break;
5674 unsigned BuiltinIndex, NumFixed = 1;
5675 bool WarnAboutSemanticsChange =
false;
5676 switch (BuiltinID) {
5677 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5678 case Builtin::BI__sync_fetch_and_add:
5679 case Builtin::BI__sync_fetch_and_add_1:
5680 case Builtin::BI__sync_fetch_and_add_2:
5681 case Builtin::BI__sync_fetch_and_add_4:
5682 case Builtin::BI__sync_fetch_and_add_8:
5683 case Builtin::BI__sync_fetch_and_add_16:
5687 case Builtin::BI__sync_fetch_and_sub:
5688 case Builtin::BI__sync_fetch_and_sub_1:
5689 case Builtin::BI__sync_fetch_and_sub_2:
5690 case Builtin::BI__sync_fetch_and_sub_4:
5691 case Builtin::BI__sync_fetch_and_sub_8:
5692 case Builtin::BI__sync_fetch_and_sub_16:
5696 case Builtin::BI__sync_fetch_and_or:
5697 case Builtin::BI__sync_fetch_and_or_1:
5698 case Builtin::BI__sync_fetch_and_or_2:
5699 case Builtin::BI__sync_fetch_and_or_4:
5700 case Builtin::BI__sync_fetch_and_or_8:
5701 case Builtin::BI__sync_fetch_and_or_16:
5705 case Builtin::BI__sync_fetch_and_and:
5706 case Builtin::BI__sync_fetch_and_and_1:
5707 case Builtin::BI__sync_fetch_and_and_2:
5708 case Builtin::BI__sync_fetch_and_and_4:
5709 case Builtin::BI__sync_fetch_and_and_8:
5710 case Builtin::BI__sync_fetch_and_and_16:
5714 case Builtin::BI__sync_fetch_and_xor:
5715 case Builtin::BI__sync_fetch_and_xor_1:
5716 case Builtin::BI__sync_fetch_and_xor_2:
5717 case Builtin::BI__sync_fetch_and_xor_4:
5718 case Builtin::BI__sync_fetch_and_xor_8:
5719 case Builtin::BI__sync_fetch_and_xor_16:
5723 case Builtin::BI__sync_fetch_and_nand:
5724 case Builtin::BI__sync_fetch_and_nand_1:
5725 case Builtin::BI__sync_fetch_and_nand_2:
5726 case Builtin::BI__sync_fetch_and_nand_4:
5727 case Builtin::BI__sync_fetch_and_nand_8:
5728 case Builtin::BI__sync_fetch_and_nand_16:
5730 WarnAboutSemanticsChange =
true;
5733 case Builtin::BI__sync_add_and_fetch:
5734 case Builtin::BI__sync_add_and_fetch_1:
5735 case Builtin::BI__sync_add_and_fetch_2:
5736 case Builtin::BI__sync_add_and_fetch_4:
5737 case Builtin::BI__sync_add_and_fetch_8:
5738 case Builtin::BI__sync_add_and_fetch_16:
5742 case Builtin::BI__sync_sub_and_fetch:
5743 case Builtin::BI__sync_sub_and_fetch_1:
5744 case Builtin::BI__sync_sub_and_fetch_2:
5745 case Builtin::BI__sync_sub_and_fetch_4:
5746 case Builtin::BI__sync_sub_and_fetch_8:
5747 case Builtin::BI__sync_sub_and_fetch_16:
5751 case Builtin::BI__sync_and_and_fetch:
5752 case Builtin::BI__sync_and_and_fetch_1:
5753 case Builtin::BI__sync_and_and_fetch_2:
5754 case Builtin::BI__sync_and_and_fetch_4:
5755 case Builtin::BI__sync_and_and_fetch_8:
5756 case Builtin::BI__sync_and_and_fetch_16:
5760 case Builtin::BI__sync_or_and_fetch:
5761 case Builtin::BI__sync_or_and_fetch_1:
5762 case Builtin::BI__sync_or_and_fetch_2:
5763 case Builtin::BI__sync_or_and_fetch_4:
5764 case Builtin::BI__sync_or_and_fetch_8:
5765 case Builtin::BI__sync_or_and_fetch_16:
5769 case Builtin::BI__sync_xor_and_fetch:
5770 case Builtin::BI__sync_xor_and_fetch_1:
5771 case Builtin::BI__sync_xor_and_fetch_2:
5772 case Builtin::BI__sync_xor_and_fetch_4:
5773 case Builtin::BI__sync_xor_and_fetch_8:
5774 case Builtin::BI__sync_xor_and_fetch_16:
5778 case Builtin::BI__sync_nand_and_fetch:
5779 case Builtin::BI__sync_nand_and_fetch_1:
5780 case Builtin::BI__sync_nand_and_fetch_2:
5781 case Builtin::BI__sync_nand_and_fetch_4:
5782 case Builtin::BI__sync_nand_and_fetch_8:
5783 case Builtin::BI__sync_nand_and_fetch_16:
5785 WarnAboutSemanticsChange =
true;
5788 case Builtin::BI__sync_val_compare_and_swap:
5789 case Builtin::BI__sync_val_compare_and_swap_1:
5790 case Builtin::BI__sync_val_compare_and_swap_2:
5791 case Builtin::BI__sync_val_compare_and_swap_4:
5792 case Builtin::BI__sync_val_compare_and_swap_8:
5793 case Builtin::BI__sync_val_compare_and_swap_16:
5798 case Builtin::BI__sync_bool_compare_and_swap:
5799 case Builtin::BI__sync_bool_compare_and_swap_1:
5800 case Builtin::BI__sync_bool_compare_and_swap_2:
5801 case Builtin::BI__sync_bool_compare_and_swap_4:
5802 case Builtin::BI__sync_bool_compare_and_swap_8:
5803 case Builtin::BI__sync_bool_compare_and_swap_16:
5809 case Builtin::BI__sync_lock_test_and_set:
5810 case Builtin::BI__sync_lock_test_and_set_1:
5811 case Builtin::BI__sync_lock_test_and_set_2:
5812 case Builtin::BI__sync_lock_test_and_set_4:
5813 case Builtin::BI__sync_lock_test_and_set_8:
5814 case Builtin::BI__sync_lock_test_and_set_16:
5818 case Builtin::BI__sync_lock_release:
5819 case Builtin::BI__sync_lock_release_1:
5820 case Builtin::BI__sync_lock_release_2:
5821 case Builtin::BI__sync_lock_release_4:
5822 case Builtin::BI__sync_lock_release_8:
5823 case Builtin::BI__sync_lock_release_16:
5829 case Builtin::BI__sync_swap:
5830 case Builtin::BI__sync_swap_1:
5831 case Builtin::BI__sync_swap_2:
5832 case Builtin::BI__sync_swap_4:
5833 case Builtin::BI__sync_swap_8:
5834 case Builtin::BI__sync_swap_16:
5842 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5843 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5844 <<
Callee->getSourceRange();
5848 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5849 <<
Callee->getSourceRange();
5851 if (WarnAboutSemanticsChange) {
5852 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5853 <<
Callee->getSourceRange();
5858 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5859 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5860 FunctionDecl *NewBuiltinDecl;
5861 if (NewBuiltinID == BuiltinID)
5862 NewBuiltinDecl = FDecl;
5865 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5868 assert(Res.getFoundDecl());
5869 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5870 if (!NewBuiltinDecl)
5877 for (
unsigned i = 0; i != NumFixed; ++i) {
5906 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5908 CK_BuiltinFnToFnPtr);
5919 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5920 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5921 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5925 return TheCallResult;
5929 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5934 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5935 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5936 "Unexpected nontemporal load/store builtin!");
5937 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5938 unsigned numArgs = isStore ? 2 : 1;
5948 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5954 PointerArg = PointerArgResult.
get();
5955 TheCall->
setArg(numArgs - 1, PointerArg);
5959 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5972 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5979 return TheCallResult;
5991 return TheCallResult;
5998 auto *
Literal = dyn_cast<StringLiteral>(Arg);
6000 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
6001 Literal = ObjcLiteral->getString();
6005 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
6012 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
6013 InitializedEntity Entity =
6023 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
6024 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
6025 TT.getArch() == llvm::Triple::aarch64_32);
6026 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
6027 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
6028 if (IsX64 || IsAArch64) {
6035 return S.
Diag(Fn->getBeginLoc(),
6036 diag::err_ms_va_start_used_in_sysv_function);
6043 (!IsWindowsOrUEFI && CC ==
CC_Win64))
6044 return S.
Diag(Fn->getBeginLoc(),
6045 diag::err_va_start_used_in_wrong_abi_function)
6046 << !IsWindowsOrUEFI;
6052 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6060 bool IsVariadic =
false;
6063 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6064 IsVariadic =
Block->isVariadic();
6065 Params =
Block->parameters();
6066 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6069 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6070 IsVariadic = MD->isVariadic();
6072 Params = MD->parameters();
6075 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6079 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6084 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6089 *LastParam = Params.empty() ?
nullptr : Params.back();
6094bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6099 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6123 ParmVarDecl *LastParam;
6134 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6136 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6141 if (std::optional<llvm::APSInt> Val =
6143 Val &&
LangOpts.C23 && *Val == 0 &&
6144 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6145 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6152 SourceLocation ParamLoc;
6153 bool IsCRegister =
false;
6154 bool SecondArgIsLastNonVariadicArgument =
false;
6155 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6156 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6157 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6160 ParamLoc = PV->getLocation();
6166 if (!SecondArgIsLastNonVariadicArgument)
6168 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6169 else if (IsCRegister ||
Type->isReferenceType() ||
6170 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6173 if (!Context.isPromotableIntegerType(Type))
6175 const auto *ED = Type->getAsEnumDecl();
6178 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6180 unsigned Reason = 0;
6181 if (
Type->isReferenceType()) Reason = 1;
6182 else if (IsCRegister) Reason = 2;
6183 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6184 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6191 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6211 if (
Call->getNumArgs() < 3)
6213 diag::err_typecheck_call_too_few_args_at_least)
6214 << 0 << 3 <<
Call->getNumArgs()
6230 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6233 const QualType &ConstCharPtrTy =
6235 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6237 << Arg1->
getType() << ConstCharPtrTy << 1
6240 << 2 << Arg1->
getType() << ConstCharPtrTy;
6242 const QualType SizeTy =
Context.getSizeType();
6247 << Arg2->
getType() << SizeTy << 1
6250 << 3 << Arg2->
getType() << SizeTy;
6255bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6259 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6287 diag::err_typecheck_call_invalid_ordered_compare)
6295bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6296 unsigned BuiltinID) {
6301 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6302 BuiltinID == Builtin::BI__builtin_isinf ||
6303 BuiltinID == Builtin::BI__builtin_isinf_sign))
6307 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6308 BuiltinID == Builtin::BI__builtin_isunordered))
6312 bool IsFPClass = NumArgs == 2;
6315 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6319 for (
unsigned i = 0; i < FPArgNo; ++i) {
6320 Expr *Arg = TheCall->
getArg(i);
6333 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6342 OrigArg = Res.
get();
6344 TheCall->
setArg(FPArgNo, OrigArg);
6346 QualType VectorResultTy;
6347 QualType ElementTy = OrigArg->
getType();
6352 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6358 diag::err_typecheck_call_invalid_unary_fp)
6370 if (!VectorResultTy.
isNull())
6371 ResultTy = VectorResultTy;
6380bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6385 for (
unsigned I = 0; I != 2; ++I) {
6386 Expr *Arg = TheCall->
getArg(I);
6396 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6411 Expr *Real = TheCall->
getArg(0);
6412 Expr *Imag = TheCall->
getArg(1);
6415 diag::err_typecheck_call_different_arg_types)
6430 diag::err_typecheck_call_too_few_args_at_least)
6431 << 0 << 2 << NumArgs
6438 unsigned NumElements = 0;
6453 unsigned NumResElements = NumArgs - 2;
6462 diag::err_vec_builtin_incompatible_vector)
6467 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6469 diag::err_vec_builtin_incompatible_vector)
6474 }
else if (NumElements != NumResElements) {
6477 ?
Context.getExtVectorType(EltType, NumResElements)
6478 :
Context.getVectorType(EltType, NumResElements,
6483 for (
unsigned I = 2; I != NumArgs; ++I) {
6491 diag::err_shufflevector_nonconstant_argument)
6497 else if (
Result->getActiveBits() > 64 ||
6498 Result->getZExtValue() >= NumElements * 2)
6500 diag::err_shufflevector_argument_too_large)
6525 diag::err_convertvector_non_vector)
6528 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6530 <<
"__builtin_convertvector");
6535 if (SrcElts != DstElts)
6537 diag::err_convertvector_incompatible_vector)
6545bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6550 diag::err_typecheck_call_too_many_args_at_most)
6551 << 0 << 3 << NumArgs << 0
6556 for (
unsigned i = 1; i != NumArgs; ++i)
6563bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6564 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6565 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6575 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6585bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6586 Expr *Arg = TheCall->
getArg(0);
6597bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6599 Expr *Arg = TheCall->
getArg(1);
6603 if (
const auto *UE =
6605 if (UE->getKind() == UETT_AlignOf ||
6606 UE->getKind() == UETT_PreferredAlignOf)
6612 if (!
Result.isPowerOf2())
6613 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6620 if (
Result > std::numeric_limits<int32_t>::max())
6628bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6633 Expr *FirstArg = TheCall->
getArg(0);
6639 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6643 TheCall->
setArg(0, FirstArgResult.
get());
6647 Expr *SecondArg = TheCall->
getArg(1);
6655 if (!
Result.isPowerOf2())
6656 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6668 Expr *ThirdArg = TheCall->
getArg(2);
6671 TheCall->
setArg(2, ThirdArg);
6677bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6678 unsigned BuiltinID =
6680 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6683 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6684 if (NumArgs < NumRequiredArgs) {
6685 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6686 << 0 << NumRequiredArgs << NumArgs
6689 if (NumArgs >= NumRequiredArgs + 0x100) {
6691 diag::err_typecheck_call_too_many_args_at_most)
6692 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6703 if (Arg.isInvalid())
6705 TheCall->
setArg(i, Arg.get());
6710 unsigned FormatIdx = i;
6720 unsigned FirstDataArg = i;
6721 while (i < NumArgs) {
6739 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6741 bool Success = CheckFormatArguments(
6744 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6768 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6777 int High,
bool RangeIsError) {
6791 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6799 PDiag(diag::warn_argument_invalid_range)
6842 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6847 if (
Value.isNegative())
6858 if ((
Value & 0xFF) != 0)
6883 Result.setIsUnsigned(
true);
6888 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6908 Result.setIsUnsigned(
true);
6916 diag::err_argument_not_shifted_byte_or_xxff)
6920bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6921 if (!Context.getTargetInfo().hasSjLjLowering())
6922 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6933 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6939bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6940 if (!Context.getTargetInfo().hasSjLjLowering())
6941 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6946bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6961 diag::err_builtin_counted_by_ref_invalid_arg)
6966 diag::err_builtin_counted_by_ref_has_side_effects)
6969 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6971 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6976 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6983 QualType MemberTy = ME->getMemberDecl()->getType();
6986 diag::err_builtin_counted_by_ref_invalid_arg)
6990 diag::err_builtin_counted_by_ref_invalid_arg)
7000bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
7002 const CallExpr *CE =
7011 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7016 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7021 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7025 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7029 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7039class UncoveredArgHandler {
7040 enum {
Unknown = -1, AllCovered = -2 };
7042 signed FirstUncoveredArg =
Unknown;
7043 SmallVector<const Expr *, 4> DiagnosticExprs;
7046 UncoveredArgHandler() =
default;
7048 bool hasUncoveredArg()
const {
7049 return (FirstUncoveredArg >= 0);
7052 unsigned getUncoveredArg()
const {
7053 assert(hasUncoveredArg() &&
"no uncovered argument");
7054 return FirstUncoveredArg;
7057 void setAllCovered() {
7060 DiagnosticExprs.clear();
7061 FirstUncoveredArg = AllCovered;
7064 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7065 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7068 if (FirstUncoveredArg == AllCovered)
7073 if (NewFirstUncoveredArg == FirstUncoveredArg)
7074 DiagnosticExprs.push_back(StrExpr);
7075 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7076 DiagnosticExprs.clear();
7077 DiagnosticExprs.push_back(StrExpr);
7078 FirstUncoveredArg = NewFirstUncoveredArg;
7082 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7085enum StringLiteralCheckType {
7087 SLCT_UncheckedLiteral,
7095 bool AddendIsRight) {
7096 unsigned BitWidth = Offset.getBitWidth();
7097 unsigned AddendBitWidth = Addend.getBitWidth();
7099 if (Addend.isUnsigned()) {
7100 Addend = Addend.zext(++AddendBitWidth);
7101 Addend.setIsSigned(
true);
7104 if (AddendBitWidth > BitWidth) {
7105 Offset = Offset.sext(AddendBitWidth);
7106 BitWidth = AddendBitWidth;
7107 }
else if (BitWidth > AddendBitWidth) {
7108 Addend = Addend.sext(BitWidth);
7112 llvm::APSInt ResOffset = Offset;
7113 if (BinOpKind == BO_Add)
7114 ResOffset = Offset.sadd_ov(Addend, Ov);
7116 assert(AddendIsRight && BinOpKind == BO_Sub &&
7117 "operator must be add or sub with addend on the right");
7118 ResOffset = Offset.ssub_ov(Addend, Ov);
7124 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7125 "index (intermediate) result too big");
7126 Offset = Offset.sext(2 * BitWidth);
7127 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7131 Offset = std::move(ResOffset);
7139class FormatStringLiteral {
7140 const StringLiteral *FExpr;
7144 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7145 : FExpr(fexpr), Offset(Offset) {}
7147 const StringLiteral *getFormatString()
const {
return FExpr; }
7149 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7151 unsigned getByteLength()
const {
7152 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7155 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7162 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7163 bool isWide()
const {
return FExpr->
isWide(); }
7164 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7165 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7166 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7167 bool isPascal()
const {
return FExpr->
isPascal(); }
7169 SourceLocation getLocationOfByte(
7170 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
7171 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7172 unsigned *StartTokenByteOffset =
nullptr)
const {
7174 StartToken, StartTokenByteOffset);
7177 SourceLocation getBeginLoc() const LLVM_READONLY {
7181 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7187 Sema &S,
const FormatStringLiteral *FExpr,
7192 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7193 bool IgnoreStringsWithoutSpecifiers);
7202static StringLiteralCheckType
7208 llvm::SmallBitVector &CheckedVarArgs,
7209 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7210 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7211 bool IgnoreStringsWithoutSpecifiers =
false) {
7213 return SLCT_NotALiteral;
7215 assert(Offset.isSigned() &&
"invalid offset");
7218 return SLCT_NotALiteral;
7227 return SLCT_UncheckedLiteral;
7230 case Stmt::InitListExprClass:
7234 format_idx, firstDataArg,
Type, CallType,
7235 false, CheckedVarArgs,
7236 UncoveredArg, Offset, CallerFormatParamIdx,
7237 IgnoreStringsWithoutSpecifiers);
7239 return SLCT_NotALiteral;
7240 case Stmt::BinaryConditionalOperatorClass:
7241 case Stmt::ConditionalOperatorClass: {
7250 bool CheckLeft =
true, CheckRight =
true;
7253 if (
C->getCond()->EvaluateAsBooleanCondition(
7265 StringLiteralCheckType Left;
7267 Left = SLCT_UncheckedLiteral;
7270 Args, APK, format_idx, firstDataArg,
Type,
7271 CallType, InFunctionCall, CheckedVarArgs,
7272 UncoveredArg, Offset, CallerFormatParamIdx,
7273 IgnoreStringsWithoutSpecifiers);
7274 if (Left == SLCT_NotALiteral || !CheckRight) {
7280 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7281 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7282 UncoveredArg, Offset, CallerFormatParamIdx,
7283 IgnoreStringsWithoutSpecifiers);
7285 return (CheckLeft && Left < Right) ? Left : Right;
7288 case Stmt::ImplicitCastExprClass:
7292 case Stmt::OpaqueValueExprClass:
7297 return SLCT_NotALiteral;
7299 case Stmt::PredefinedExprClass:
7303 return SLCT_UncheckedLiteral;
7305 case Stmt::DeclRefExprClass: {
7311 bool isConstant =
false;
7315 isConstant = AT->getElementType().isConstant(S.
Context);
7317 isConstant = T.isConstant(S.
Context) &&
7318 PT->getPointeeType().isConstant(S.
Context);
7319 }
else if (T->isObjCObjectPointerType()) {
7322 isConstant = T.isConstant(S.
Context);
7326 if (
const Expr *
Init = VD->getAnyInitializer()) {
7329 if (InitList->isStringLiteralInit())
7330 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7333 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7334 firstDataArg,
Type, CallType,
false,
7335 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7386 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7387 if (CallerFormatParamIdx)
7388 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7389 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7390 for (
const auto *PVFormatMatches :
7391 D->specific_attrs<FormatMatchesAttr>()) {
7396 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7400 S.
Diag(Args[format_idx]->getBeginLoc(),
7401 diag::warn_format_string_type_incompatible)
7402 << PVFormatMatches->getType()->getName()
7404 if (!InFunctionCall) {
7405 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7406 diag::note_format_string_defined);
7408 return SLCT_UncheckedLiteral;
7411 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7412 Args, APK, format_idx, firstDataArg,
Type, CallType,
7413 false, CheckedVarArgs, UncoveredArg,
7414 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7418 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7421 PVFormat->getFirstArg(), &CallerFSI))
7423 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7427 S.
Diag(Args[format_idx]->getBeginLoc(),
7428 diag::warn_format_string_type_incompatible)
7429 << PVFormat->getType()->getName()
7431 if (!InFunctionCall) {
7434 return SLCT_UncheckedLiteral;
7447 return SLCT_UncheckedLiteral;
7455 return SLCT_NotALiteral;
7458 case Stmt::CallExprClass:
7459 case Stmt::CXXMemberCallExprClass: {
7463 StringLiteralCheckType CommonResult;
7464 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7465 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7467 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7468 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7469 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7476 return CommonResult;
7478 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7480 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7481 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7484 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7485 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7486 UncoveredArg, Offset, CallerFormatParamIdx,
7487 IgnoreStringsWithoutSpecifiers);
7493 format_idx, firstDataArg,
Type, CallType,
7494 false, CheckedVarArgs,
7495 UncoveredArg, Offset, CallerFormatParamIdx,
7496 IgnoreStringsWithoutSpecifiers);
7497 return SLCT_NotALiteral;
7499 case Stmt::ObjCMessageExprClass: {
7501 if (
const auto *MD = ME->getMethodDecl()) {
7502 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7511 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7513 MD->getSelector().isKeywordSelector(
7514 {
"localizedStringForKey",
"value",
"table"})) {
7515 IgnoreStringsWithoutSpecifiers =
true;
7518 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7520 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7521 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7522 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7526 return SLCT_NotALiteral;
7528 case Stmt::ObjCStringLiteralClass:
7529 case Stmt::StringLiteralClass: {
7538 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7541 return SLCT_NotALiteral;
7543 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7545 format_idx, firstDataArg,
Type, InFunctionCall,
7546 CallType, CheckedVarArgs, UncoveredArg,
7547 IgnoreStringsWithoutSpecifiers);
7548 return SLCT_CheckedLiteral;
7551 return SLCT_NotALiteral;
7553 case Stmt::BinaryOperatorClass: {
7567 if (LIsInt != RIsInt) {
7571 if (BinOpKind == BO_Add) {
7584 return SLCT_NotALiteral;
7586 case Stmt::UnaryOperatorClass: {
7588 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7589 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7591 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7601 return SLCT_NotALiteral;
7605 return SLCT_NotALiteral;
7616 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7617 if (isa_and_nonnull<StringLiteral>(LVE))
7638 return "freebsd_kprintf";
7647 return llvm::StringSwitch<FormatStringType>(Flavor)
7649 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7654 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7670bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7674 llvm::SmallBitVector &CheckedVarArgs) {
7675 FormatStringInfo FSI;
7679 return CheckFormatArguments(
7680 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7685bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7689 llvm::SmallBitVector &CheckedVarArgs) {
7690 FormatStringInfo FSI;
7694 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7695 Format->getFormatString(), FSI.FormatIdx,
7697 CallType, Loc, Range, CheckedVarArgs);
7705 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7718 unsigned CallerArgumentIndexOffset =
7721 unsigned FirstArgumentIndex = -1;
7731 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7732 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7736 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7737 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7739 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7742 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7743 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7746 FirstArgumentIndex =
7747 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7753 ? (NumCallerParams + CallerArgumentIndexOffset)
7758 if (!ReferenceFormatString)
7764 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7766 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7768 std::string
Attr, Fixit;
7769 llvm::raw_string_ostream AttrOS(
Attr);
7771 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7772 << FirstArgumentIndex <<
")";
7774 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7776 AttrOS.write_escaped(ReferenceFormatString->
getString());
7780 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7791 llvm::raw_string_ostream IS(Fixit);
7799 if (LO.C23 || LO.CPlusPlus11)
7800 IS <<
"[[gnu::" <<
Attr <<
"]]";
7801 else if (LO.ObjC || LO.GNUMode)
7802 IS <<
"__attribute__((" <<
Attr <<
"))";
7816 Caller->
addAttr(FormatAttr::CreateImplicit(
7818 FormatStringIndex, FirstArgumentIndex));
7820 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7822 FormatStringIndex, ReferenceFormatString));
7826 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7838 unsigned format_idx,
unsigned firstDataArg,
7842 llvm::SmallBitVector &CheckedVarArgs) {
7844 if (format_idx >= Args.size()) {
7845 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7849 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7863 UncoveredArgHandler UncoveredArg;
7864 std::optional<unsigned> CallerParamIdx;
7866 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7867 firstDataArg,
Type, CallType,
7868 true, CheckedVarArgs, UncoveredArg,
7869 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7872 if (UncoveredArg.hasUncoveredArg()) {
7873 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7874 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7875 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7878 if (CT != SLCT_NotALiteral)
7880 return CT == SLCT_CheckedLiteral;
7886 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7892 this, Args, APK, ReferenceFormatString, format_idx,
7893 firstDataArg,
Type, *CallerParamIdx, Loc))
7903 if (Args.size() == firstDataArg) {
7904 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7912 Diag(FormatLoc, diag::note_format_security_fixit)
7916 Diag(FormatLoc, diag::note_format_security_fixit)
7921 Diag(FormatLoc, diag::warn_format_nonliteral)
7932 const FormatStringLiteral *FExpr;
7933 const Expr *OrigFormatExpr;
7935 const unsigned FirstDataArg;
7936 const unsigned NumDataArgs;
7939 ArrayRef<const Expr *> Args;
7941 llvm::SmallBitVector CoveredArgs;
7942 bool usesPositionalArgs =
false;
7943 bool atFirstArg =
true;
7944 bool inFunctionCall;
7946 llvm::SmallBitVector &CheckedVarArgs;
7947 UncoveredArgHandler &UncoveredArg;
7950 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
7952 unsigned firstDataArg,
unsigned numDataArgs,
7954 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7956 llvm::SmallBitVector &CheckedVarArgs,
7957 UncoveredArgHandler &UncoveredArg)
7958 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7959 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7960 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7961 inFunctionCall(inFunctionCall), CallType(callType),
7962 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7963 CoveredArgs.resize(numDataArgs);
7964 CoveredArgs.reset();
7967 bool HasFormatArguments()
const {
7972 void DoneProcessing();
7974 void HandleIncompleteSpecifier(
const char *startSpecifier,
7975 unsigned specifierLen)
override;
7977 void HandleInvalidLengthModifier(
7978 const analyze_format_string::FormatSpecifier &FS,
7979 const analyze_format_string::ConversionSpecifier &CS,
7980 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
7982 void HandleNonStandardLengthModifier(
7983 const analyze_format_string::FormatSpecifier &FS,
7984 const char *startSpecifier,
unsigned specifierLen);
7986 void HandleNonStandardConversionSpecifier(
7987 const analyze_format_string::ConversionSpecifier &CS,
7988 const char *startSpecifier,
unsigned specifierLen);
7990 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7992 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
7995 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7997 void HandleNullChar(
const char *nullCharacter)
override;
7999 template <
typename Range>
8001 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
8002 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
8003 bool IsStringLocation, Range StringRange,
8004 ArrayRef<FixItHint> Fixit = {});
8007 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
8008 const char *startSpec,
8009 unsigned specifierLen,
8010 const char *csStart,
unsigned csLen);
8012 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
8013 const char *startSpec,
8014 unsigned specifierLen);
8016 SourceRange getFormatStringRange();
8017 CharSourceRange getSpecifierRange(
const char *startSpecifier,
8018 unsigned specifierLen);
8019 SourceLocation getLocationOfByte(
const char *x);
8021 const Expr *getDataArg(
unsigned i)
const;
8023 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
8024 const analyze_format_string::ConversionSpecifier &CS,
8025 const char *startSpecifier,
unsigned specifierLen,
8028 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
8029 const Expr *E,
const char *startSpecifier,
8030 unsigned specifierLen);
8032 template <
typename Range>
8033 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
8034 bool IsStringLocation, Range StringRange,
8035 ArrayRef<FixItHint> Fixit = {});
8040SourceRange CheckFormatHandler::getFormatStringRange() {
8045CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8046 unsigned specifierLen) {
8048 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8056SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8061void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8062 unsigned specifierLen) {
8063 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8064 getLocationOfByte(startSpecifier),
8066 getSpecifierRange(startSpecifier, specifierLen));
8069bool CheckFormatHandler::CheckUnsupportedType(
8071 const char *StartSpecifier,
unsigned SpecifierLen) {
8075 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8078 getSpecifierRange(StartSpecifier, SpecifierLen));
8082void CheckFormatHandler::HandleInvalidLengthModifier(
8085 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8097 getSpecifierRange(startSpecifier, specifierLen));
8099 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8100 << FixedLM->toString()
8105 if (DiagID == diag::warn_format_nonsensical_length)
8111 getSpecifierRange(startSpecifier, specifierLen), Hint);
8115void CheckFormatHandler::HandleNonStandardLengthModifier(
8117 const char *startSpecifier,
unsigned specifierLen) {
8126 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8130 getSpecifierRange(startSpecifier, specifierLen));
8132 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8133 << FixedLM->toString()
8137 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8141 getSpecifierRange(startSpecifier, specifierLen));
8145void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8147 const char *startSpecifier,
unsigned specifierLen) {
8153 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8157 getSpecifierRange(startSpecifier, specifierLen));
8160 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8161 << FixedCS->toString()
8164 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8168 getSpecifierRange(startSpecifier, specifierLen));
8172void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8174 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8175 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8176 getLocationOfByte(startPos),
8178 getSpecifierRange(startPos, posLen));
8181void CheckFormatHandler::HandleInvalidPosition(
8182 const char *startSpecifier,
unsigned specifierLen,
8185 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8186 EmitFormatDiagnostic(
8187 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8188 getLocationOfByte(startSpecifier),
true,
8189 getSpecifierRange(startSpecifier, specifierLen));
8192void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8196 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8197 getLocationOfByte(startPos),
8199 getSpecifierRange(startPos, posLen));
8202void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8205 EmitFormatDiagnostic(
8206 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8207 getLocationOfByte(nullCharacter),
true,
8208 getFormatStringRange());
8214const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8215 return Args[FirstDataArg + i];
8218void CheckFormatHandler::DoneProcessing() {
8221 if (HasFormatArguments()) {
8224 signed notCoveredArg = CoveredArgs.find_first();
8225 if (notCoveredArg >= 0) {
8226 assert((
unsigned)notCoveredArg < NumDataArgs);
8227 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8229 UncoveredArg.setAllCovered();
8234void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8235 const Expr *ArgExpr) {
8236 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8247 for (
auto E : DiagnosticExprs)
8250 CheckFormatHandler::EmitFormatDiagnostic(
8251 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8255bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8257 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8258 bool keepGoing =
true;
8259 if (argIndex < NumDataArgs) {
8262 CoveredArgs.set(argIndex);
8277 std::string CodePointStr;
8278 if (!llvm::sys::locale::isPrint(*csStart)) {
8279 llvm::UTF32 CodePoint;
8280 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8281 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8282 llvm::ConversionResult
Result =
8283 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8285 if (
Result != llvm::conversionOK) {
8286 unsigned char FirstChar = *csStart;
8287 CodePoint = (llvm::UTF32)FirstChar;
8290 llvm::raw_string_ostream
OS(CodePointStr);
8291 if (CodePoint < 256)
8292 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8293 else if (CodePoint <= 0xFFFF)
8294 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8296 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8300 EmitFormatDiagnostic(
8301 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8302 true, getSpecifierRange(startSpec, specifierLen));
8307void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8308 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8309 EmitFormatDiagnostic(
8310 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8311 true, getSpecifierRange(startSpec, specifierLen));
8314bool CheckFormatHandler::CheckNumArgs(
8317 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8319 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8322 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8323 << (argIndex + 1) << NumDataArgs)
8324 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8325 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8327 getSpecifierRange(startSpecifier, specifierLen));
8331 UncoveredArg.setAllCovered();
8337template <
typename Range>
8340 bool IsStringLocation,
8343 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8344 IsStringLocation, StringRange, FixIt);
8374template <
typename Range>
8375void CheckFormatHandler::EmitFormatDiagnostic(
8376 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8379 if (InFunctionCall) {
8384 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8388 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8389 diag::note_format_string_defined);
8391 Note << StringRange;
8400class CheckPrintfHandler :
public CheckFormatHandler {
8402 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8404 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8406 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8408 llvm::SmallBitVector &CheckedVarArgs,
8409 UncoveredArgHandler &UncoveredArg)
8410 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8411 numDataArgs, beg, APK, Args, formatIdx,
8412 inFunctionCall, CallType, CheckedVarArgs,
8415 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8418 bool allowsObjCArg()
const {
8419 return FSType == FormatStringType::NSString ||
8420 FSType == FormatStringType::OSLog ||
8421 FSType == FormatStringType::OSTrace;
8424 bool HandleInvalidPrintfConversionSpecifier(
8425 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8426 unsigned specifierLen)
override;
8428 void handleInvalidMaskType(StringRef MaskType)
override;
8430 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8431 const char *startSpecifier,
unsigned specifierLen,
8432 const TargetInfo &
Target)
override;
8433 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8434 const char *StartSpecifier,
unsigned SpecifierLen,
8437 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8438 unsigned k,
const char *startSpecifier,
8439 unsigned specifierLen);
8440 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8441 const analyze_printf::OptionalAmount &Amt,
8442 unsigned type,
const char *startSpecifier,
8443 unsigned specifierLen);
8444 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8445 const analyze_printf::OptionalFlag &flag,
8446 const char *startSpecifier,
unsigned specifierLen);
8447 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8448 const analyze_printf::OptionalFlag &ignoredFlag,
8449 const analyze_printf::OptionalFlag &flag,
8450 const char *startSpecifier,
unsigned specifierLen);
8451 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8453 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8454 unsigned flagLen)
override;
8456 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8457 unsigned flagLen)
override;
8460 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8461 const char *flagsEnd,
8462 const char *conversionPosition)
override;
8467class EquatableFormatArgument {
8469 enum SpecifierSensitivity :
unsigned {
8476 enum FormatArgumentRole :
unsigned {
8484 analyze_format_string::ArgType ArgType;
8485 analyze_format_string::LengthModifier LengthMod;
8486 StringRef SpecifierLetter;
8487 CharSourceRange
Range;
8488 SourceLocation ElementLoc;
8489 FormatArgumentRole
Role : 2;
8490 SpecifierSensitivity Sensitivity : 2;
8491 unsigned Position : 14;
8492 unsigned ModifierFor : 14;
8494 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8495 bool InFunctionCall)
const;
8498 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8499 analyze_format_string::LengthModifier LengthMod,
8500 StringRef SpecifierLetter,
8501 analyze_format_string::ArgType ArgType,
8502 FormatArgumentRole
Role,
8503 SpecifierSensitivity Sensitivity,
unsigned Position,
8504 unsigned ModifierFor)
8505 : ArgType(ArgType), LengthMod(LengthMod),
8506 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8507 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8508 ModifierFor(ModifierFor) {}
8510 unsigned getPosition()
const {
return Position; }
8511 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8513 analyze_format_string::LengthModifier getLengthModifier()
const {
8516 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8518 std::string buildFormatSpecifier()
const {
8520 llvm::raw_string_ostream(result)
8521 << getLengthModifier().
toString() << SpecifierLetter;
8525 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8526 const Expr *FmtExpr,
bool InFunctionCall)
const;
8530class DecomposePrintfHandler :
public CheckPrintfHandler {
8531 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8534 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8535 const Expr *origFormatExpr,
8537 unsigned numDataArgs,
bool isObjC,
const char *beg,
8539 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8541 llvm::SmallBitVector &CheckedVarArgs,
8542 UncoveredArgHandler &UncoveredArg,
8543 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8544 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8545 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8546 inFunctionCall, CallType, CheckedVarArgs,
8548 Specs(Specs), HadError(
false) {}
8552 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8554 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8556 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8557 const char *startSpecifier,
8558 unsigned specifierLen,
8559 const TargetInfo &
Target)
override;
8564bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8566 unsigned specifierLen) {
8570 return HandleInvalidConversionSpecifier(
8575void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8576 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8584 return T->isRecordType() || T->isComplexType();
8587bool CheckPrintfHandler::HandleAmount(
8589 const char *startSpecifier,
unsigned specifierLen) {
8591 if (HasFormatArguments()) {
8593 if (argIndex >= NumDataArgs) {
8594 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8598 getSpecifierRange(startSpecifier, specifierLen));
8608 CoveredArgs.set(argIndex);
8609 const Expr *Arg = getDataArg(argIndex);
8620 ? diag::err_printf_asterisk_wrong_type
8621 : diag::warn_printf_asterisk_wrong_type;
8622 EmitFormatDiagnostic(S.
PDiag(DiagID)
8627 getSpecifierRange(startSpecifier, specifierLen));
8637void CheckPrintfHandler::HandleInvalidAmount(
8640 const char *startSpecifier,
unsigned specifierLen) {
8650 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8654 getSpecifierRange(startSpecifier, specifierLen), fixit);
8659 const char *startSpecifier,
8660 unsigned specifierLen) {
8664 EmitFormatDiagnostic(
8665 S.
PDiag(diag::warn_printf_nonsensical_flag)
8669 getSpecifierRange(startSpecifier, specifierLen),
8673void CheckPrintfHandler::HandleIgnoredFlag(
8677 unsigned specifierLen) {
8679 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8683 getSpecifierRange(startSpecifier, specifierLen),
8685 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8688void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8691 EmitFormatDiagnostic(
8692 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8693 true, getSpecifierRange(startFlag, flagLen));
8696void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8699 auto Range = getSpecifierRange(startFlag, flagLen);
8700 StringRef flag(startFlag, flagLen);
8701 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8702 getLocationOfByte(startFlag),
8707void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8708 const char *flagsStart,
const char *flagsEnd,
8709 const char *conversionPosition) {
8711 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8712 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8713 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8714 getLocationOfByte(conversionPosition),
8720 const Expr *FmtExpr,
8721 bool InFunctionCall)
const {
8722 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8723 ElementLoc,
true, Range);
8726bool EquatableFormatArgument::VerifyCompatible(
8727 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8728 bool InFunctionCall)
const {
8733 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8734 FmtExpr, InFunctionCall);
8735 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8739 if (
Role != FAR_Data) {
8740 if (ModifierFor !=
Other.ModifierFor) {
8743 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8744 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8745 FmtExpr, InFunctionCall);
8746 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8752 bool HadError =
false;
8753 if (Sensitivity !=
Other.Sensitivity) {
8756 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8757 << Sensitivity <<
Other.Sensitivity,
8758 FmtExpr, InFunctionCall);
8759 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8760 << 0 <<
Other.Range;
8763 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8767 case MK::MatchPromotion:
8771 case MK::NoMatchTypeConfusion:
8772 case MK::NoMatchPromotionTypeConfusion:
8774 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8775 << buildFormatSpecifier()
8776 <<
Other.buildFormatSpecifier(),
8777 FmtExpr, InFunctionCall);
8778 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8779 << 0 <<
Other.Range;
8782 case MK::NoMatchPedantic:
8784 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8785 << buildFormatSpecifier()
8786 <<
Other.buildFormatSpecifier(),
8787 FmtExpr, InFunctionCall);
8788 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8789 << 0 <<
Other.Range;
8792 case MK::NoMatchSignedness:
8794 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8795 << buildFormatSpecifier()
8796 <<
Other.buildFormatSpecifier(),
8797 FmtExpr, InFunctionCall);
8798 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8799 << 0 <<
Other.Range;
8805bool DecomposePrintfHandler::GetSpecifiers(
8806 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8809 StringRef
Data = FSL->getString();
8810 const char *Str =
Data.data();
8811 llvm::SmallBitVector BV;
8812 UncoveredArgHandler UA;
8813 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8814 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8826 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8827 const EquatableFormatArgument &B) {
8828 return A.getPosition() < B.getPosition();
8833bool DecomposePrintfHandler::HandlePrintfSpecifier(
8836 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8851 const unsigned Unset = ~0;
8852 unsigned FieldWidthIndex = Unset;
8853 unsigned PrecisionIndex = Unset;
8857 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8858 FieldWidthIndex = Specs.size();
8860 getSpecifierRange(startSpecifier, specifierLen),
8861 getLocationOfByte(FieldWidth.getStart()),
8863 FieldWidth.getArgType(S.
Context),
8864 EquatableFormatArgument::FAR_FieldWidth,
8865 EquatableFormatArgument::SS_None,
8866 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
8872 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8873 PrecisionIndex = Specs.size();
8875 getSpecifierRange(startSpecifier, specifierLen),
8876 getLocationOfByte(Precision.getStart()),
8878 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8879 EquatableFormatArgument::SS_None,
8880 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8886 unsigned SpecIndex =
8888 if (FieldWidthIndex != Unset)
8889 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8890 if (PrecisionIndex != Unset)
8891 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8893 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8895 Sensitivity = EquatableFormatArgument::SS_Private;
8897 Sensitivity = EquatableFormatArgument::SS_Public;
8899 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8901 Sensitivity = EquatableFormatArgument::SS_None;
8904 getSpecifierRange(startSpecifier, specifierLen),
8907 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8912 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8917 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8918 SpecIndex + 1, SpecIndex);
8926template<
typename MemberKind>
8937 R.suppressDiagnostics();
8944 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8959 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8961 if ((*MI)->getMinRequiredArguments() == 0)
8969bool CheckPrintfHandler::checkForCStrMembers(
8976 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8979 if (
Method->getMinRequiredArguments() == 0 &&
8992bool CheckPrintfHandler::HandlePrintfSpecifier(
9005 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
9006 startSpecifier, specifierLen);
9018 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
9023 if (!CS.consumesDataArgument()) {
9031 if (argIndex < NumDataArgs) {
9035 CoveredArgs.set(argIndex);
9042 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9045 if (HasFormatArguments()) {
9047 CoveredArgs.set(argIndex + 1);
9050 const Expr *Ex = getDataArg(argIndex);
9054 : ArgType::CPointerTy;
9056 EmitFormatDiagnostic(
9057 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9061 getSpecifierRange(startSpecifier, specifierLen));
9064 Ex = getDataArg(argIndex + 1);
9067 EmitFormatDiagnostic(
9068 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9072 getSpecifierRange(startSpecifier, specifierLen));
9079 if (!allowsObjCArg() && CS.isObjCArg()) {
9080 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9087 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9094 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9095 getLocationOfByte(CS.getStart()),
9097 getSpecifierRange(startSpecifier, specifierLen));
9107 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9114 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9118 getSpecifierRange(startSpecifier, specifierLen));
9121 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9125 getSpecifierRange(startSpecifier, specifierLen));
9129 const llvm::Triple &Triple =
Target.getTriple();
9131 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9132 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9133 getLocationOfByte(CS.getStart()),
9135 getSpecifierRange(startSpecifier, specifierLen));
9141 startSpecifier, specifierLen);
9147 startSpecifier, specifierLen);
9153 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9154 getLocationOfByte(startSpecifier),
9156 getSpecifierRange(startSpecifier, specifierLen));
9165 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9167 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9176 startSpecifier, specifierLen);
9179 startSpecifier, specifierLen);
9184 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9185 diag::warn_format_nonsensical_length);
9187 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9189 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9190 diag::warn_format_non_standard_conversion_spec);
9193 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9196 if (!HasFormatArguments())
9199 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9202 const Expr *Arg = getDataArg(argIndex);
9206 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9218 case Stmt::ArraySubscriptExprClass:
9219 case Stmt::CallExprClass:
9220 case Stmt::CharacterLiteralClass:
9221 case Stmt::CXXBoolLiteralExprClass:
9222 case Stmt::DeclRefExprClass:
9223 case Stmt::FloatingLiteralClass:
9224 case Stmt::IntegerLiteralClass:
9225 case Stmt::MemberExprClass:
9226 case Stmt::ObjCArrayLiteralClass:
9227 case Stmt::ObjCBoolLiteralExprClass:
9228 case Stmt::ObjCBoxedExprClass:
9229 case Stmt::ObjCDictionaryLiteralClass:
9230 case Stmt::ObjCEncodeExprClass:
9231 case Stmt::ObjCIvarRefExprClass:
9232 case Stmt::ObjCMessageExprClass:
9233 case Stmt::ObjCPropertyRefExprClass:
9234 case Stmt::ObjCStringLiteralClass:
9235 case Stmt::ObjCSubscriptRefExprClass:
9236 case Stmt::ParenExprClass:
9237 case Stmt::StringLiteralClass:
9238 case Stmt::UnaryOperatorClass:
9245static std::pair<QualType, StringRef>
9251 StringRef Name = UserTy->getDecl()->getName();
9252 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9253 .Case(
"CFIndex", Context.getNSIntegerType())
9254 .Case(
"NSInteger", Context.getNSIntegerType())
9255 .Case(
"NSUInteger", Context.getNSUIntegerType())
9256 .Case(
"SInt32", Context.IntTy)
9257 .Case(
"UInt32", Context.UnsignedIntTy)
9261 return std::make_pair(CastTy, Name);
9263 TyTy = UserTy->desugar();
9267 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9277 StringRef TrueName, FalseName;
9280 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9282 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9284 if (TrueTy == FalseTy)
9285 return std::make_pair(TrueTy, TrueName);
9286 else if (TrueTy.
isNull())
9287 return std::make_pair(FalseTy, FalseName);
9288 else if (FalseTy.
isNull())
9289 return std::make_pair(TrueTy, TrueName);
9292 return std::make_pair(
QualType(), StringRef());
9311 From = VecTy->getElementType();
9313 To = VecTy->getElementType();
9324 diag::warn_format_conversion_argument_type_mismatch_signedness,
9328 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9335bool CheckPrintfHandler::checkFormatExpr(
9337 unsigned SpecifierLen,
const Expr *E) {
9348 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9349 ExprTy = TET->getUnderlyingExpr()->getType();
9352 if (
const OverflowBehaviorType *OBT =
9354 ExprTy = OBT->getUnderlyingType();
9368 getSpecifierRange(StartSpecifier, SpecifierLen);
9370 llvm::raw_svector_ostream os(FSString);
9372 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9383 getSpecifierRange(StartSpecifier, SpecifierLen);
9384 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9389 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9397 if (
Match == ArgType::Match)
9401 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9410 E = ICE->getSubExpr();
9420 if (OrigMatch == ArgType::NoMatchSignedness &&
9421 ImplicitMatch != ArgType::NoMatchSignedness)
9428 if (ImplicitMatch == ArgType::Match)
9446 if (
Match == ArgType::MatchPromotion)
9450 if (
Match == ArgType::MatchPromotion) {
9454 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9455 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9459 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9460 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9461 Match = ImplicitMatch;
9462 assert(
Match != ArgType::MatchPromotion);
9465 bool IsEnum =
false;
9466 bool IsScopedEnum =
false;
9469 IntendedTy = ED->getIntegerType();
9470 if (!ED->isScoped()) {
9471 ExprTy = IntendedTy;
9476 IsScopedEnum =
true;
9483 if (isObjCContext() &&
9494 const llvm::APInt &
V = IL->getValue();
9504 if (TD->getUnderlyingType() == IntendedTy)
9514 bool ShouldNotPrintDirectly =
false;
9515 StringRef CastTyName;
9518 std::tie(CastTy, CastTyName) =
9524 if (!IsScopedEnum &&
9525 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9529 IntendedTy = CastTy;
9530 ShouldNotPrintDirectly =
true;
9535 PrintfSpecifier fixedFS = FS;
9542 llvm::raw_svector_ostream os(buf);
9545 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9547 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9553 llvm_unreachable(
"expected non-matching");
9555 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9558 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9561 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9564 Diag = diag::warn_format_conversion_argument_type_mismatch;
9585 llvm::raw_svector_ostream CastFix(CastBuf);
9586 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9588 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9594 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9599 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9621 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9627 Name = TypedefTy->getDecl()->getName();
9631 ? diag::warn_format_argument_needs_cast_pedantic
9632 : diag::warn_format_argument_needs_cast;
9633 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9644 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9645 : diag::warn_format_conversion_argument_type_mismatch;
9647 EmitFormatDiagnostic(
9655 getSpecifierRange(StartSpecifier, SpecifierLen);
9659 bool EmitTypeMismatch =
false;
9663 bool EmitOSLogError =
false;
9672 llvm_unreachable(
"expected non-matching");
9674 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9677 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9680 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9684 Diag = diag::warn_format_conversion_argument_type_mismatch;
9688 if (!EmitOSLogError)
9689 EmitFormatDiagnostic(
9698 EmitTypeMismatch =
true;
9702 EmitOSLogError =
true;
9704 EmitFormatDiagnostic(
9705 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9706 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9710 checkForCStrMembers(AT, E);
9716 EmitTypeMismatch =
true;
9718 EmitFormatDiagnostic(
9719 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9720 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9734 EmitFormatDiagnostic(
9735 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
9740 if (EmitTypeMismatch) {
9746 EmitFormatDiagnostic(
9747 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9753 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9754 "format string specifier index out of range");
9755 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9765class CheckScanfHandler :
public CheckFormatHandler {
9767 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
9769 unsigned firstDataArg,
unsigned numDataArgs,
9771 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9773 llvm::SmallBitVector &CheckedVarArgs,
9774 UncoveredArgHandler &UncoveredArg)
9775 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
9776 numDataArgs, beg, APK, Args, formatIdx,
9777 inFunctionCall, CallType, CheckedVarArgs,
9780 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9781 const char *startSpecifier,
9782 unsigned specifierLen)
override;
9785 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9786 const char *startSpecifier,
9787 unsigned specifierLen)
override;
9789 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9794void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9796 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9797 getLocationOfByte(end),
true,
9798 getSpecifierRange(start, end - start));
9801bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9803 unsigned specifierLen) {
9807 return HandleInvalidConversionSpecifier(
9812bool CheckScanfHandler::HandleScanfSpecifier(
9814 unsigned specifierLen) {
9827 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9828 startSpecifier, specifierLen);
9839 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9854 if (argIndex < NumDataArgs) {
9858 CoveredArgs.set(argIndex);
9864 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9865 diag::warn_format_nonsensical_length);
9867 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9869 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9870 diag::warn_format_non_standard_conversion_spec);
9873 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9876 if (!HasFormatArguments())
9879 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9883 const Expr *Ex = getDataArg(argIndex);
9893 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
9904 ScanfSpecifier fixedFS = FS;
9909 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9911 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9912 : diag::warn_format_conversion_argument_type_mismatch;
9917 llvm::raw_svector_ostream os(buf);
9920 EmitFormatDiagnostic(
9925 getSpecifierRange(startSpecifier, specifierLen),
9927 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9934 getSpecifierRange(startSpecifier, specifierLen));
9944 const Expr *FmtExpr,
bool InFunctionCall) {
9945 bool HadError =
false;
9946 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9947 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9948 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9960 for (; FmtIter < FmtEnd; ++FmtIter) {
9964 if (FmtIter->getPosition() < RefIter->getPosition())
9968 if (FmtIter->getPosition() > RefIter->getPosition())
9972 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9976 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9977 return Arg.getPosition() != RefIter->getPosition();
9981 if (FmtIter < FmtEnd) {
9982 CheckFormatHandler::EmitFormatDiagnostic(
9983 S, InFunctionCall, FmtExpr,
9984 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9985 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9986 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9987 }
else if (RefIter < RefEnd) {
9988 CheckFormatHandler::EmitFormatDiagnostic(
9989 S, InFunctionCall, FmtExpr,
9990 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9993 << 1 << RefIter->getSourceRange();
9999 Sema &S,
const FormatStringLiteral *FExpr,
10004 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
10005 bool IgnoreStringsWithoutSpecifiers) {
10007 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
10008 CheckFormatHandler::EmitFormatDiagnostic(
10009 S, inFunctionCall, Args[format_idx],
10010 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
10016 StringRef StrRef = FExpr->getString();
10017 const char *Str = StrRef.data();
10021 assert(T &&
"String literal not of constant array type!");
10022 size_t TypeSize = T->getZExtSize();
10023 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10024 const unsigned numDataArgs = Args.size() - firstDataArg;
10026 if (IgnoreStringsWithoutSpecifiers &&
10033 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
10034 CheckFormatHandler::EmitFormatDiagnostic(
10035 S, inFunctionCall, Args[format_idx],
10036 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
10037 FExpr->getBeginLoc(),
10043 if (StrLen == 0 && numDataArgs > 0) {
10044 CheckFormatHandler::EmitFormatDiagnostic(
10045 S, inFunctionCall, Args[format_idx],
10046 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10057 if (ReferenceFormatString ==
nullptr) {
10058 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10059 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10060 inFunctionCall, CallType, CheckedVarArgs,
10067 H.DoneProcessing();
10070 Type, ReferenceFormatString, FExpr->getFormatString(),
10071 inFunctionCall ?
nullptr : Args[format_idx]);
10074 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10075 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10076 CallType, CheckedVarArgs, UncoveredArg);
10080 H.DoneProcessing();
10096 FormatStringLiteral RefLit = AuthoritativeFormatString;
10097 FormatStringLiteral TestLit = TestedFormatString;
10099 bool DiagAtStringLiteral;
10100 if (FunctionCallArg) {
10101 Arg = FunctionCallArg;
10102 DiagAtStringLiteral =
false;
10104 Arg = TestedFormatString;
10105 DiagAtStringLiteral =
true;
10107 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10108 AuthoritativeFormatString,
Type,
10109 IsObjC,
true, RefArgs) &&
10110 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10111 DiagAtStringLiteral, FmtArgs)) {
10113 TestedFormatString, FmtArgs, Arg,
10114 DiagAtStringLiteral);
10127 FormatStringLiteral RefLit = Str;
10131 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10140 bool HadError =
false;
10141 auto Iter = Args.begin();
10142 auto End = Args.end();
10143 while (Iter != End) {
10144 const auto &FirstInGroup = *Iter;
10146 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10148 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10157 const char *Str = StrRef.data();
10160 assert(T &&
"String literal not of constant array type!");
10161 size_t TypeSize = T->getZExtSize();
10162 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10172 switch (AbsFunction) {
10176 case Builtin::BI__builtin_abs:
10177 return Builtin::BI__builtin_labs;
10178 case Builtin::BI__builtin_labs:
10179 return Builtin::BI__builtin_llabs;
10180 case Builtin::BI__builtin_llabs:
10183 case Builtin::BI__builtin_fabsf:
10184 return Builtin::BI__builtin_fabs;
10185 case Builtin::BI__builtin_fabs:
10186 return Builtin::BI__builtin_fabsl;
10187 case Builtin::BI__builtin_fabsl:
10190 case Builtin::BI__builtin_cabsf:
10191 return Builtin::BI__builtin_cabs;
10192 case Builtin::BI__builtin_cabs:
10193 return Builtin::BI__builtin_cabsl;
10194 case Builtin::BI__builtin_cabsl:
10197 case Builtin::BIabs:
10198 return Builtin::BIlabs;
10199 case Builtin::BIlabs:
10200 return Builtin::BIllabs;
10201 case Builtin::BIllabs:
10204 case Builtin::BIfabsf:
10205 return Builtin::BIfabs;
10206 case Builtin::BIfabs:
10207 return Builtin::BIfabsl;
10208 case Builtin::BIfabsl:
10211 case Builtin::BIcabsf:
10212 return Builtin::BIcabs;
10213 case Builtin::BIcabs:
10214 return Builtin::BIcabsl;
10215 case Builtin::BIcabsl:
10222 unsigned AbsType) {
10244 unsigned AbsFunctionKind) {
10245 unsigned BestKind = 0;
10246 uint64_t ArgSize = Context.getTypeSize(ArgType);
10247 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10250 if (Context.getTypeSize(ParamType) >= ArgSize) {
10253 else if (Context.hasSameType(ParamType, ArgType)) {
10269 if (T->isIntegralOrEnumerationType())
10271 if (T->isRealFloatingType())
10273 if (T->isAnyComplexType())
10276 llvm_unreachable(
"Type not integer, floating, or complex");
10283 switch (ValueKind) {
10288 case Builtin::BI__builtin_fabsf:
10289 case Builtin::BI__builtin_fabs:
10290 case Builtin::BI__builtin_fabsl:
10291 case Builtin::BI__builtin_cabsf:
10292 case Builtin::BI__builtin_cabs:
10293 case Builtin::BI__builtin_cabsl:
10294 return Builtin::BI__builtin_abs;
10295 case Builtin::BIfabsf:
10296 case Builtin::BIfabs:
10297 case Builtin::BIfabsl:
10298 case Builtin::BIcabsf:
10299 case Builtin::BIcabs:
10300 case Builtin::BIcabsl:
10301 return Builtin::BIabs;
10307 case Builtin::BI__builtin_abs:
10308 case Builtin::BI__builtin_labs:
10309 case Builtin::BI__builtin_llabs:
10310 case Builtin::BI__builtin_cabsf:
10311 case Builtin::BI__builtin_cabs:
10312 case Builtin::BI__builtin_cabsl:
10313 return Builtin::BI__builtin_fabsf;
10314 case Builtin::BIabs:
10315 case Builtin::BIlabs:
10316 case Builtin::BIllabs:
10317 case Builtin::BIcabsf:
10318 case Builtin::BIcabs:
10319 case Builtin::BIcabsl:
10320 return Builtin::BIfabsf;
10326 case Builtin::BI__builtin_abs:
10327 case Builtin::BI__builtin_labs:
10328 case Builtin::BI__builtin_llabs:
10329 case Builtin::BI__builtin_fabsf:
10330 case Builtin::BI__builtin_fabs:
10331 case Builtin::BI__builtin_fabsl:
10332 return Builtin::BI__builtin_cabsf;
10333 case Builtin::BIabs:
10334 case Builtin::BIlabs:
10335 case Builtin::BIllabs:
10336 case Builtin::BIfabsf:
10337 case Builtin::BIfabs:
10338 case Builtin::BIfabsl:
10339 return Builtin::BIcabsf;
10342 llvm_unreachable(
"Unable to convert function");
10353 case Builtin::BI__builtin_abs:
10354 case Builtin::BI__builtin_fabs:
10355 case Builtin::BI__builtin_fabsf:
10356 case Builtin::BI__builtin_fabsl:
10357 case Builtin::BI__builtin_labs:
10358 case Builtin::BI__builtin_llabs:
10359 case Builtin::BI__builtin_cabs:
10360 case Builtin::BI__builtin_cabsf:
10361 case Builtin::BI__builtin_cabsl:
10362 case Builtin::BIabs:
10363 case Builtin::BIlabs:
10364 case Builtin::BIllabs:
10365 case Builtin::BIfabs:
10366 case Builtin::BIfabsf:
10367 case Builtin::BIfabsl:
10368 case Builtin::BIcabs:
10369 case Builtin::BIcabsf:
10370 case Builtin::BIcabsl:
10373 llvm_unreachable(
"Unknown Builtin type");
10379 unsigned AbsKind,
QualType ArgType) {
10380 bool EmitHeaderHint =
true;
10381 const char *HeaderName =
nullptr;
10382 std::string FunctionName;
10383 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10384 FunctionName =
"std::abs";
10385 if (ArgType->isIntegralOrEnumerationType()) {
10386 HeaderName =
"cstdlib";
10387 }
else if (ArgType->isRealFloatingType()) {
10388 HeaderName =
"cmath";
10390 llvm_unreachable(
"Invalid Type");
10396 R.suppressDiagnostics();
10399 for (
const auto *I : R) {
10402 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10404 FDecl = dyn_cast<FunctionDecl>(I);
10419 EmitHeaderHint =
false;
10431 R.suppressDiagnostics();
10434 if (R.isSingleResult()) {
10435 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10437 EmitHeaderHint =
false;
10441 }
else if (!R.empty()) {
10447 S.
Diag(Loc, diag::note_replace_abs_function)
10453 if (!EmitHeaderHint)
10456 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10460template <std::
size_t StrLen>
10462 const char (&Str)[StrLen]) {
10475 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10476 return llvm::is_contained(names, calleeName);
10481 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10482 "__builtin_nanf16",
"__builtin_nanf128"});
10484 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10485 "__builtin_inff16",
"__builtin_inff128"});
10487 llvm_unreachable(
"unknown MathCheck");
10491 if (FDecl->
getName() !=
"infinity")
10494 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10496 if (RDecl->
getName() !=
"numeric_limits")
10513 if (FPO.getNoHonorNaNs() &&
10516 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10517 << 1 << 0 <<
Call->getSourceRange();
10521 if (FPO.getNoHonorInfs() &&
10525 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10526 << 0 << 0 <<
Call->getSourceRange();
10530void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10532 if (
Call->getNumArgs() != 1)
10537 if (AbsKind == 0 && !IsStdAbs)
10540 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10541 QualType ParamType =
Call->getArg(0)->getType();
10546 std::string FunctionName =
10547 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10548 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10549 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10584 if (ArgValueKind == ParamValueKind) {
10585 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10589 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10590 << FDecl << ArgType << ParamType;
10592 if (NewAbsKind == 0)
10596 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10605 if (NewAbsKind == 0)
10608 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10609 << FDecl << ParamValueKind << ArgValueKind;
10612 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10618 if (!
Call || !FDecl)
return;
10622 if (
Call->getExprLoc().isMacroID())
return;
10625 if (
Call->getNumArgs() != 2)
return;
10628 if (!ArgList)
return;
10629 if (ArgList->size() != 1)
return;
10632 const auto& TA = ArgList->
get(0);
10634 QualType ArgType = TA.getAsType();
10638 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10639 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10640 if (!MTE)
return false;
10641 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10642 if (!
Num)
return false;
10643 if (
Num->getValue() != 0)
return false;
10647 const Expr *FirstArg =
Call->getArg(0);
10648 const Expr *SecondArg =
Call->getArg(1);
10649 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10650 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10653 if (IsFirstArgZero == IsSecondArgZero)
return;
10658 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10660 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10661 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10664 SourceRange RemovalRange;
10665 if (IsFirstArgZero) {
10666 RemovalRange = SourceRange(FirstRange.
getBegin(),
10673 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10688 const auto *Size = dyn_cast<BinaryOperator>(E);
10693 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10697 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10698 << SizeRange << FnName;
10699 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10704 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10715 bool &IsContained) {
10718 IsContained =
false;
10731 for (
auto *FD : RD->
fields()) {
10735 IsContained =
true;
10736 return ContainedRD;
10744 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10745 if (Unary->getKind() == UETT_SizeOf)
10754 if (!
SizeOf->isArgumentType())
10755 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10762 return SizeOf->getTypeOfArgument();
10768struct SearchNonTrivialToInitializeField
10771 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10773 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10776 SourceLocation SL) {
10777 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10778 asDerived().visitArray(PDIK, AT, SL);
10782 Super::visitWithKind(PDIK, FT, SL);
10785 void visitARCStrong(QualType FT, SourceLocation SL) {
10788 void visitARCWeak(QualType FT, SourceLocation SL) {
10791 void visitStruct(QualType FT, SourceLocation SL) {
10796 const ArrayType *AT, SourceLocation SL) {
10797 visit(getContext().getBaseElementType(AT), SL);
10799 void visitTrivial(QualType FT, SourceLocation SL) {}
10801 static void diag(QualType RT,
const Expr *E, Sema &S) {
10802 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10811struct SearchNonTrivialToCopyField
10813 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10815 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10818 SourceLocation SL) {
10819 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10820 asDerived().visitArray(PCK, AT, SL);
10824 Super::visitWithKind(PCK, FT, SL);
10827 void visitARCStrong(QualType FT, SourceLocation SL) {
10830 void visitARCWeak(QualType FT, SourceLocation SL) {
10833 void visitPtrAuth(QualType FT, SourceLocation SL) {
10836 void visitStruct(QualType FT, SourceLocation SL) {
10841 SourceLocation SL) {
10842 visit(getContext().getBaseElementType(AT), SL);
10845 SourceLocation SL) {}
10846 void visitTrivial(QualType FT, SourceLocation SL) {}
10847 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10849 static void diag(QualType RT,
const Expr *E, Sema &S) {
10850 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10865 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10866 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10890 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10892 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10893 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10899 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10902 const Expr *SizeArg =
10903 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10905 auto isLiteralZero = [](
const Expr *E) {
10915 if (isLiteralZero(SizeArg) &&
10922 if (BId == Builtin::BIbzero ||
10925 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10926 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10927 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10928 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10929 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10937 if (BId == Builtin::BImemset &&
10941 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10942 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10947void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10954 unsigned ExpectedNumArgs =
10955 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10956 if (
Call->getNumArgs() < ExpectedNumArgs)
10959 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10960 BId == Builtin::BIstrndup ? 1 : 2);
10962 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10966 Call->getBeginLoc(),
Call->getRParenLoc()))
10978 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10979 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10982 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10986 QualType DestTy = Dest->
getType();
10987 QualType PointeeTy;
10988 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
11000 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
11006 if (SizeOfArgTy != QualType()) {
11008 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
11010 PDiag(diag::warn_sizeof_pointer_type_memaccess)
11011 << FnName << SizeOfArgTy << ArgIdx
11018 PointeeTy = DestTy;
11021 if (PointeeTy == QualType())
11026 if (
const CXXRecordDecl *ContainedRD =
11029 unsigned OperationType = 0;
11030 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
11033 if (ArgIdx != 0 || IsCmp) {
11034 if (BId == Builtin::BImemcpy)
11036 else if(BId == Builtin::BImemmove)
11043 PDiag(diag::warn_dyn_class_memaccess)
11044 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
11045 << IsContained << ContainedRD << OperationType
11046 <<
Call->getCallee()->getSourceRange());
11048 BId != Builtin::BImemset)
11051 PDiag(diag::warn_arc_object_memaccess)
11052 << ArgIdx << FnName << PointeeTy
11053 <<
Call->getCallee()->getSourceRange());
11060 bool NonTriviallyCopyableCXXRecord =
11064 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11067 PDiag(diag::warn_cstruct_memaccess)
11068 << ArgIdx << FnName << PointeeTy << 0);
11069 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11070 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11071 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11075 PDiag(diag::warn_cxxstruct_memaccess)
11076 << FnName << PointeeTy);
11077 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11080 PDiag(diag::warn_cstruct_memaccess)
11081 << ArgIdx << FnName << PointeeTy << 1);
11082 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11083 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11084 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11088 PDiag(diag::warn_cxxstruct_memaccess)
11089 << FnName << PointeeTy);
11098 PDiag(diag::note_bad_memaccess_silence)
11104bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11106 llvm::FoldingSetNodeID SizeOfArgID;
11112 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11115 QualType DestTy = Dest->
getType();
11116 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11122 if (SizeOfArgID == llvm::FoldingSetNodeID())
11125 llvm::FoldingSetNodeID DestID;
11127 if (DestID == SizeOfArgID) {
11130 unsigned ActionIdx = 0;
11131 StringRef ReadableName = FnName->
getName();
11133 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11134 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11143 SourceLocation SL = SizeOfArg->
getExprLoc();
11148 if (
SM.isMacroArgExpansion(SL)) {
11150 SL =
SM.getSpellingLoc(SL);
11151 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
11153 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
11158 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11159 << ReadableName << PointeeTy << DestTy << DSR
11162 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11163 << ActionIdx << SSR);
11199 if (CAT->getZExtSize() <= 1)
11207void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11211 unsigned NumArgs =
Call->getNumArgs();
11212 if ((NumArgs != 3) && (NumArgs != 4))
11217 const Expr *CompareWithSrc =
nullptr;
11220 Call->getBeginLoc(),
Call->getRParenLoc()))
11225 CompareWithSrc = Ex;
11228 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11229 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11230 SizeCall->getNumArgs() == 1)
11235 if (!CompareWithSrc)
11242 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11246 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11247 if (!CompareWithSrcDRE ||
11251 const Expr *OriginalSizeArg =
Call->getArg(2);
11252 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11259 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11263 SmallString<128> sizeString;
11264 llvm::raw_svector_ostream
OS(sizeString);
11269 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11276 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11277 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11278 return D1->getDecl() == D2->getDecl();
11283 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11292void Sema::CheckStrncatArguments(
const CallExpr *CE,
11307 unsigned PatternType = 0;
11315 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11316 if (BE->getOpcode() == BO_Sub) {
11317 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11318 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11329 if (PatternType == 0)
11338 if (
SM.isMacroArgExpansion(SL)) {
11339 SL =
SM.getSpellingLoc(SL);
11340 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11345 QualType DstTy = DstArg->
getType();
11348 if (!isKnownSizeArray) {
11349 if (PatternType == 1)
11350 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11352 Diag(SL, diag::warn_strncat_src_size) << SR;
11356 if (PatternType == 1)
11357 Diag(SL, diag::warn_strncat_large_size) << SR;
11359 Diag(SL, diag::warn_strncat_src_size) << SR;
11361 SmallString<128> sizeString;
11362 llvm::raw_svector_ostream
OS(sizeString);
11370 Diag(SL, diag::note_strncat_wrong_size)
11375void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11384void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11386 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11387 const Decl *D = Lvalue->getDecl();
11388 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11389 if (!DD->getType()->isReferenceType())
11390 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11394 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11395 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11396 Lvalue->getMemberDecl());
11399void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11401 const auto *Lambda = dyn_cast<LambdaExpr>(
11406 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11407 << CalleeName << 2 ;
11410void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11412 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11413 if (Var ==
nullptr)
11417 << CalleeName << 0 << Var;
11420void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11423 llvm::raw_svector_ostream
OS(SizeString);
11426 if (Kind == clang::CK_BitCast &&
11427 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11429 if (Kind == clang::CK_IntegralToPointer &&
11431 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11434 switch (
Cast->getCastKind()) {
11435 case clang::CK_BitCast:
11436 case clang::CK_IntegralToPointer:
11437 case clang::CK_FunctionToPointerDecay:
11446 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11447 << CalleeName << 0 <<
OS.str();
11451void Sema::CheckFreeArguments(
const CallExpr *E) {
11452 const std::string CalleeName =
11457 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11459 case UnaryOperator::Opcode::UO_AddrOf:
11460 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11461 case UnaryOperator::Opcode::UO_Plus:
11462 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11467 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11469 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11471 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11472 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11473 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11479 << CalleeName << 1 ;
11484 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11485 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11489Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11498 Diag(ReturnLoc, diag::warn_null_ret)
11508 if (Op == OO_New || Op == OO_Array_New) {
11509 const FunctionProtoType *Proto
11513 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11519 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11524 if (
Context.getTargetInfo().getTriple().isPPC64())
11536 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11537 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11538 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11539 return FPLiteral && FPCast;
11542 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11548 llvm::APFloat TargetC = FPLiteral->
getValue();
11549 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11550 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11554 Diag(Loc, diag::warn_float_compare_literal)
11555 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11568 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11569 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11570 if (DRL->getDecl() == DRR->getDecl())
11578 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11579 if (FLL->isExact())
11581 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11582 if (FLR->isExact())
11586 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11587 CL &&
CL->getBuiltinCallee())
11590 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11591 CR && CR->getBuiltinCallee())
11595 Diag(Loc, diag::warn_floatingpoint_eq)
11616 IntRange(
unsigned Width,
bool NonNegative)
11617 : Width(Width), NonNegative(NonNegative) {}
11620 unsigned valueBits()
const {
11621 return NonNegative ? Width : Width - 1;
11625 static IntRange forBoolType() {
11626 return IntRange(1,
true);
11630 static IntRange forValueOfType(ASTContext &
C, QualType T) {
11631 return forValueOfCanonicalType(
C,
11636 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *T) {
11639 if (
const auto *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 auto *CT = dyn_cast<ComplexType>(T))
11644 T = CT->getElementType().getTypePtr();
11645 if (
const auto *AT = dyn_cast<AtomicType>(T))
11646 T = AT->getValueType().getTypePtr();
11647 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11648 T = OBT->getUnderlyingType().getTypePtr();
11650 if (!
C.getLangOpts().CPlusPlus) {
11653 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11658 if (
Enum->isFixed()) {
11659 return IntRange(
C.getIntWidth(QualType(T, 0)),
11660 !
Enum->getIntegerType()->isSignedIntegerType());
11663 unsigned NumPositive =
Enum->getNumPositiveBits();
11664 unsigned NumNegative =
Enum->getNumNegativeBits();
11666 if (NumNegative == 0)
11667 return IntRange(NumPositive,
true);
11669 return IntRange(std::max(NumPositive + 1, NumNegative),
11673 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11674 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11687 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *T) {
11690 if (
const VectorType *VT = dyn_cast<VectorType>(T))
11691 T = VT->getElementType().getTypePtr();
11692 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11693 T = MT->getElementType().getTypePtr();
11694 if (
const ComplexType *CT = dyn_cast<ComplexType>(T))
11695 T = CT->getElementType().getTypePtr();
11696 if (
const AtomicType *AT = dyn_cast<AtomicType>(T))
11697 T = AT->getValueType().getTypePtr();
11699 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11700 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11701 T = OBT->getUnderlyingType().getTypePtr();
11703 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11704 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11713 static IntRange
join(IntRange L, IntRange R) {
11714 bool Unsigned = L.NonNegative &&
R.NonNegative;
11715 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11716 L.NonNegative &&
R.NonNegative);
11720 static IntRange bit_and(IntRange L, IntRange R) {
11721 unsigned Bits = std::max(L.Width,
R.Width);
11722 bool NonNegative =
false;
11723 if (L.NonNegative) {
11724 Bits = std::min(Bits, L.Width);
11725 NonNegative =
true;
11727 if (
R.NonNegative) {
11728 Bits = std::min(Bits,
R.Width);
11729 NonNegative =
true;
11731 return IntRange(Bits, NonNegative);
11735 static IntRange sum(IntRange L, IntRange R) {
11736 bool Unsigned = L.NonNegative &&
R.NonNegative;
11737 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11742 static IntRange difference(IntRange L, IntRange R) {
11746 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11747 bool Unsigned = L.NonNegative &&
R.Width == 0;
11748 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11754 static IntRange product(IntRange L, IntRange R) {
11758 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11759 bool Unsigned = L.NonNegative &&
R.NonNegative;
11760 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11765 static IntRange rem(IntRange L, IntRange R) {
11769 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11777 if (value.isSigned() && value.isNegative())
11778 return IntRange(value.getSignificantBits(),
false);
11780 if (value.getBitWidth() > MaxWidth)
11781 value = value.trunc(MaxWidth);
11785 return IntRange(value.getActiveBits(),
true);
11789 if (result.
isInt())
11796 R = IntRange::join(R, El);
11804 return IntRange::join(R, I);
11819 Ty = AtomicRHS->getValueType();
11838 bool InConstantContext,
11839 bool Approximate) {
11850 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11851 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11855 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11857 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11858 CE->getCastKind() == CK_BooleanToSignedIntegral;
11861 if (!isIntegerCast)
11862 return OutputTypeRange;
11865 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11866 InConstantContext, Approximate);
11868 return std::nullopt;
11871 if (SubRange->Width >= OutputTypeRange.Width)
11872 return OutputTypeRange;
11876 return IntRange(SubRange->Width,
11877 SubRange->NonNegative || OutputTypeRange.NonNegative);
11880 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11883 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11885 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11886 InConstantContext, Approximate);
11891 Expr *TrueExpr = CO->getTrueExpr();
11893 return std::nullopt;
11895 std::optional<IntRange> L =
11898 return std::nullopt;
11900 Expr *FalseExpr = CO->getFalseExpr();
11902 return std::nullopt;
11904 std::optional<IntRange> R =
11907 return std::nullopt;
11909 return IntRange::join(*L, *R);
11912 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11913 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11915 switch (BO->getOpcode()) {
11917 llvm_unreachable(
"builtin <=> should have class type");
11928 return IntRange::forBoolType();
11957 Combine = IntRange::bit_and;
11965 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11966 if (I->getValue() == 1) {
11967 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11968 return IntRange(R.Width,
true);
11978 case BO_ShrAssign: {
11980 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11982 return std::nullopt;
11986 if (std::optional<llvm::APSInt> shift =
11987 BO->getRHS()->getIntegerConstantExpr(
C)) {
11988 if (shift->isNonNegative()) {
11989 if (shift->uge(L->Width))
11990 L->Width = (L->NonNegative ? 0 : 1);
11992 L->Width -= shift->getZExtValue();
12006 Combine = IntRange::sum;
12010 if (BO->getLHS()->getType()->isPointerType())
12013 Combine = IntRange::difference;
12018 Combine = IntRange::product;
12027 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
12029 return std::nullopt;
12032 if (std::optional<llvm::APSInt> divisor =
12033 BO->getRHS()->getIntegerConstantExpr(
C)) {
12034 unsigned log2 = divisor->logBase2();
12035 if (
log2 >= L->Width)
12036 L->Width = (L->NonNegative ? 0 : 1);
12038 L->Width = std::min(L->Width -
log2, MaxWidth);
12046 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
12048 return std::nullopt;
12050 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12054 Combine = IntRange::rem;
12066 unsigned opWidth =
C.getIntWidth(T);
12068 InConstantContext, Approximate);
12070 return std::nullopt;
12073 InConstantContext, Approximate);
12075 return std::nullopt;
12077 IntRange
C = Combine(*L, *R);
12078 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
12079 C.Width = std::min(
C.Width, MaxWidth);
12083 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12084 switch (UO->getOpcode()) {
12087 return IntRange::forBoolType();
12101 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12104 return std::nullopt;
12109 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12119 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12122 return std::nullopt;
12127 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12137 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
12138 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
12142 return IntRange(BitField->getBitWidthValue(),
12143 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12146 return std::nullopt;
12152 bool InConstantContext,
12153 bool Approximate) {
12162 const llvm::fltSemantics &Src,
12163 const llvm::fltSemantics &Tgt) {
12164 llvm::APFloat truncated = value;
12167 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12168 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12170 return truncated.bitwiseIsEqual(value);
12179 const llvm::fltSemantics &Src,
12180 const llvm::fltSemantics &Tgt) {
12204 bool IsListInit =
false);
12219 return MacroName !=
"YES" && MacroName !=
"NO" &&
12220 MacroName !=
"true" && MacroName !=
"false";
12228 (!E->
getType()->isSignedIntegerType() ||
12243struct PromotedRange {
12245 llvm::APSInt PromotedMin;
12247 llvm::APSInt PromotedMax;
12249 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12251 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12252 else if (
R.Width >= BitWidth && !
Unsigned) {
12256 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12257 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12259 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12260 .extOrTrunc(BitWidth);
12261 PromotedMin.setIsUnsigned(
Unsigned);
12263 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12264 .extOrTrunc(BitWidth);
12265 PromotedMax.setIsUnsigned(
Unsigned);
12270 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12280 InRangeFlag = 0x40,
12283 Min =
LE | InRangeFlag,
12284 InRange = InRangeFlag,
12285 Max =
GE | InRangeFlag,
12288 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12293 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12294 Value.isUnsigned() == PromotedMin.isUnsigned());
12295 if (!isContiguous()) {
12296 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12297 if (
Value.isMinValue())
return Min;
12298 if (
Value.isMaxValue())
return Max;
12299 if (
Value >= PromotedMin)
return InRange;
12300 if (
Value <= PromotedMax)
return InRange;
12304 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12305 case -1:
return Less;
12306 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12308 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12309 case -1:
return InRange;
12310 case 0:
return Max;
12315 llvm_unreachable(
"impossible compare result");
12318 static std::optional<StringRef>
12320 if (Op == BO_Cmp) {
12322 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12324 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12325 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12326 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12327 return std::nullopt;
12334 }
else if (Op == BO_NE) {
12338 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12345 if (Op == BO_GE || Op == BO_LE)
12346 std::swap(TrueFlag, FalseFlag);
12349 return StringRef(
"true");
12351 return StringRef(
"false");
12352 return std::nullopt;
12359 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12360 if (ICE->getCastKind() != CK_IntegralCast &&
12361 ICE->getCastKind() != CK_NoOp)
12363 E = ICE->getSubExpr();
12372 enum ConstantValueKind {
12377 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12378 return BL->getValue() ? ConstantValueKind::LiteralTrue
12379 : ConstantValueKind::LiteralFalse;
12380 return ConstantValueKind::Miscellaneous;
12385 const llvm::APSInt &
Value,
12386 bool RhsConstant) {
12402 if (
Constant->getType()->isEnumeralType() &&
12408 if (!OtherValueRange)
12413 OtherT = AT->getValueType();
12414 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12418 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12424 bool OtherIsBooleanDespiteType =
12426 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12427 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12431 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12432 Value.isUnsigned());
12433 auto Cmp = OtherPromotedValueRange.compare(
Value);
12440 bool TautologicalTypeCompare =
false;
12442 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12443 Value.isUnsigned());
12444 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12447 TautologicalTypeCompare =
true;
12455 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12464 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12470 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12471 Other->getType()->isUnsignedIntegerOrEnumerationType())
12472 TautologicalTypeCompare =
true;
12477 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12478 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12482 llvm::raw_svector_ostream OS(PrettySourceValue);
12484 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12485 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12486 Constant->IgnoreParenImpCasts())) {
12487 OS << (BL->getValue() ?
"YES" :
"NO");
12492 if (!TautologicalTypeCompare) {
12494 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12500 if (IsObjCSignedCharBool) {
12502 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12503 << OS.str() << *
Result);
12510 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12514 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12515 : diag::warn_tautological_bool_compare)
12517 << OtherIsBooleanDespiteType << *
Result
12524 ? diag::warn_unsigned_enum_always_true_comparison
12525 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12526 : diag::warn_unsigned_always_true_comparison)
12527 : diag::warn_tautological_constant_compare;
12563 if (T->isIntegralType(S.
Context)) {
12564 std::optional<llvm::APSInt> RHSValue =
12566 std::optional<llvm::APSInt> LHSValue =
12570 if (RHSValue && LHSValue)
12574 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12576 const bool RhsConstant = (
bool)RHSValue;
12577 Expr *Const = RhsConstant ? RHS : LHS;
12579 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12588 if (!T->hasUnsignedIntegerRepresentation()) {
12602 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12604 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12610 Expr *signedOperand, *unsignedOperand;
12613 "unsigned comparison between two signed integer expressions?");
12614 signedOperand = LHS;
12615 unsignedOperand = RHS;
12617 signedOperand = RHS;
12618 unsignedOperand = LHS;
12624 std::optional<IntRange> signedRange =
12636 if (signedRange->NonNegative)
12648 if (!unsignedRange)
12653 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12655 if (unsignedRange->Width < comparisonWidth)
12660 S.
PDiag(diag::warn_mixed_sign_comparison)
12679 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12684 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12685 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12686 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12687 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12688 << BitfieldEnumDecl;
12695 Init->isValueDependent() ||
12696 Init->isTypeDependent())
12699 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12709 const PreferredTypeAttr *PTAttr =
nullptr;
12711 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12713 ED = PTAttr->getType()->getAsEnumDecl();
12721 bool SignedEnum = ED->getNumNegativeBits() > 0;
12728 unsigned DiagID = 0;
12729 if (SignedEnum && !SignedBitfield) {
12732 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12734 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12735 }
else if (SignedBitfield && !SignedEnum &&
12736 ED->getNumPositiveBits() == FieldWidth) {
12739 ? diag::warn_signed_bitfield_enum_conversion
12740 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12743 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12748 << SignedEnum << TypeRange;
12750 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12757 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12758 ED->getNumNegativeBits())
12759 : ED->getNumPositiveBits();
12762 if (BitsNeeded > FieldWidth) {
12766 ? diag::warn_bitfield_too_small_for_enum
12767 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12768 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12772 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12782 unsigned OriginalWidth =
Value.getBitWidth();
12788 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12789 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12796 if (!
Value.isSigned() ||
Value.isNegative())
12797 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12798 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12799 OriginalWidth =
Value.getSignificantBits();
12801 if (OriginalWidth <= FieldWidth)
12805 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12809 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12810 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12814 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12816 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12817 ? diag::warn_impcast_single_bit_bitield_precision_constant
12818 : diag::warn_impcast_bitfield_precision_constant)
12819 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12820 <<
Init->getSourceRange();
12857 bool PruneControlFlow =
false) {
12864 if (T.hasAddressSpace())
12866 if (PruneControlFlow) {
12880 bool PruneControlFlow =
false) {
12887 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
12892 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12893 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12898 llvm::APFloat
Value(0.0);
12904 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12909 diag::warn_impcast_float_integer, PruneWarnings);
12912 bool isExact =
false;
12915 T->hasUnsignedIntegerRepresentation());
12916 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
12917 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12925 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12926 precision = (precision * 59 + 195) / 196;
12927 Value.toString(PrettySourceValue, precision);
12931 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12932 << PrettySourceValue);
12935 if (
Result == llvm::APFloat::opOK && isExact) {
12936 if (IsLiteral)
return;
12937 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
12943 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
12946 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12947 : diag::warn_impcast_float_to_integer_out_of_range,
12950 unsigned DiagID = 0;
12953 DiagID = diag::warn_impcast_literal_float_to_integer;
12954 }
else if (IntegerValue == 0) {
12955 if (
Value.isZero()) {
12957 diag::warn_impcast_float_integer, PruneWarnings);
12960 DiagID = diag::warn_impcast_float_to_integer_zero;
12962 if (IntegerValue.isUnsigned()) {
12963 if (!IntegerValue.isMaxValue()) {
12965 diag::warn_impcast_float_integer, PruneWarnings);
12968 if (!IntegerValue.isMaxSignedValue() &&
12969 !IntegerValue.isMinSignedValue()) {
12971 diag::warn_impcast_float_integer, PruneWarnings);
12975 DiagID = diag::warn_impcast_float_to_integer;
12980 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12982 IntegerValue.toString(PrettyTargetValue);
12984 if (PruneWarnings) {
12988 << PrettySourceValue << PrettyTargetValue
13001 "Must be compound assignment operation");
13012 ->getComputationResultType()
13019 if (ResultBT->isInteger())
13021 E->
getExprLoc(), diag::warn_impcast_float_integer);
13023 if (!ResultBT->isFloatingPoint())
13032 diag::warn_impcast_float_result_precision);
13037 if (!Range.Width)
return "0";
13039 llvm::APSInt ValueInRange =
Value;
13040 ValueInRange.setIsSigned(!Range.NonNegative);
13041 ValueInRange = ValueInRange.trunc(Range.Width);
13042 return toString(ValueInRange, 10);
13052 const Type *Source =
13054 if (
Target->isDependentType())
13057 const auto *FloatCandidateBT =
13058 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13059 const Type *BoolCandidateType = ToBool ?
Target : Source;
13062 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13067 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13073 S, TheCall->
getArg(I - 1),
false));
13075 S, TheCall->
getArg(I + 1),
false));
13080 diag::warn_impcast_floating_point_to_bool);
13095 if (!IsGNUNullExpr && !HasNullPtrType)
13099 if (T->isAnyPointerType() || T->isBlockPointerType() ||
13100 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
13103 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13116 if (IsGNUNullExpr && Loc.
isMacroID()) {
13119 if (MacroName ==
"NULL")
13127 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13141 const char FirstLiteralCharacter =
13143 if (FirstLiteralCharacter ==
'0')
13149 if (CC.
isValid() && T->isCharType()) {
13150 const char FirstContextCharacter =
13152 if (FirstContextCharacter ==
'{')
13160 const auto *IL = dyn_cast<IntegerLiteral>(E);
13162 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13163 if (UO->getOpcode() == UO_Minus)
13164 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13175 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13179 if (Opc == BO_Shl) {
13182 if (LHS && LHS->getValue() == 0)
13183 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13185 RHS->getValue().isNonNegative() &&
13187 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13188 << (
Result.Val.getInt() != 0);
13190 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13197 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13202 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13203 (RHS->getValue() == 0 || RHS->getValue() == 1))
13206 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13207 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13215 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13221 if (Source->isChar16Type() &&
Target->isChar32Type())
13227 llvm::APSInt
Value(32);
13229 bool IsASCII =
Value <= 0x7F;
13230 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13231 bool ConversionPreservesSemantics =
13232 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13234 if (!ConversionPreservesSemantics) {
13235 auto IsSingleCodeUnitCP = [](
const QualType &T,
13236 const llvm::APSInt &
Value) {
13237 if (T->isChar8Type())
13238 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13239 if (T->isChar16Type())
13240 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13241 assert(T->isChar32Type());
13242 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13245 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13254 LosesPrecision ? diag::warn_impcast_unicode_precision
13255 : diag::warn_impcast_unicode_char_type);
13260 From =
Context.getCanonicalType(From);
13261 To =
Context.getCanonicalType(To);
13264 From = MaybePointee;
13271 if (FromFn->getCFIUncheckedCalleeAttr() &&
13272 !ToFn->getCFIUncheckedCalleeAttr())
13280 bool *ICContext,
bool IsListInit) {
13285 if (Source ==
Target)
return;
13286 if (
Target->isDependentType())
return;
13296 if (Source->isAtomicType())
13300 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13306 diag::warn_impcast_string_literal_to_bool);
13312 diag::warn_impcast_objective_c_literal_to_bool);
13314 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13326 if (
ObjC().isSignedCharBool(T) && Source->isIntegralType(
Context)) {
13329 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13331 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13340 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13342 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13353 diag::err_impcast_incompatible_type);
13358 ? diag::err_impcast_complex_scalar
13359 : diag::warn_impcast_complex_scalar);
13368 if (
Target->isSveVLSBuiltinType() &&
13375 if (
Target->isRVVVLSBuiltinType() &&
13385 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_vector_scalar);
13393 diag::warn_hlsl_impcast_vector_truncation);
13405 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13406 Target = VecTy->getElementType().getTypePtr();
13410 if (
Target->isScalarType())
13411 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_matrix_scalar);
13419 diag::warn_hlsl_impcast_matrix_truncation);
13425 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13426 Target = MatTy->getElementType().getTypePtr();
13428 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13434 const Type *OriginalTarget =
Context.getCanonicalType(T).getTypePtr();
13437 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13439 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13478 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_float_precision);
13481 else if (Order < 0) {
13485 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_double_promotion);
13491 if (TargetBT && TargetBT->
isInteger()) {
13518 diag::warn_impcast_floating_point_to_bool);
13526 if (Source->isFixedPointType()) {
13527 if (
Target->isUnsaturatedFixedPointType()) {
13531 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13532 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(T);
13533 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(T);
13536 PDiag(diag::warn_impcast_fixed_point_range)
13537 <<
Value.toString() << T
13543 }
else if (
Target->isIntegerType()) {
13547 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13550 llvm::APSInt IntResult = FXResult.convertToInt(
13551 Context.getIntWidth(T),
Target->isSignedIntegerOrEnumerationType(),
13556 PDiag(diag::warn_impcast_fixed_point_range)
13557 << FXResult.toString() << T
13564 }
else if (
Target->isUnsaturatedFixedPointType()) {
13565 if (Source->isIntegerType()) {
13572 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13573 Value,
Context.getFixedPointSemantics(T), &Overflowed);
13577 PDiag(diag::warn_impcast_fixed_point_range)
13598 unsigned int SourcePrecision =
SourceRange->Width;
13602 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13605 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13606 SourcePrecision > TargetPrecision) {
13608 if (std::optional<llvm::APSInt> SourceInt =
13613 llvm::APFloat TargetFloatValue(
13615 llvm::APFloat::opStatus ConversionStatus =
13616 TargetFloatValue.convertFromAPInt(
13618 llvm::APFloat::rmNearestTiesToEven);
13620 if (ConversionStatus != llvm::APFloat::opOK) {
13622 SourceInt->toString(PrettySourceValue, 10);
13624 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13628 PDiag(diag::warn_impcast_integer_float_precision_constant)
13629 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13635 diag::warn_impcast_integer_float_precision);
13644 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13649 if (
Target->isBooleanType())
13653 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13657 if (!Source->isIntegerType() || !
Target->isIntegerType())
13662 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13665 if (
ObjC().isSignedCharBool(T) && !Source->isCharType() &&
13668 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13673 if (!LikelySourceRange)
13676 IntRange SourceTypeRange =
13677 IntRange::forTargetOfCanonicalType(
Context, Source);
13678 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13680 if (LikelySourceRange->Width > TargetRange.Width) {
13684 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13685 if (TargetOBT->isWrapKind()) {
13692 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13693 if (SourceOBT->isWrapKind()) {
13703 llvm::APSInt
Value(32);
13713 PDiag(diag::warn_impcast_integer_precision_constant)
13714 << PrettySourceValue << PrettyTargetValue
13724 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13725 if (UO->getOpcode() == UO_Minus)
13727 *
this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
13730 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13731 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_integer_64_32,
13734 diag::warn_impcast_integer_precision);
13737 if (TargetRange.Width > SourceTypeRange.Width) {
13738 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13739 if (UO->getOpcode() == UO_Minus)
13740 if (Source->isUnsignedIntegerType()) {
13741 if (
Target->isUnsignedIntegerType())
13743 diag::warn_impcast_high_order_zero_bits);
13744 if (
Target->isSignedIntegerType())
13746 diag::warn_impcast_nonnegative_result);
13750 if (TargetRange.Width == LikelySourceRange->Width &&
13751 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13752 Source->isSignedIntegerType()) {
13766 PDiag(diag::warn_impcast_integer_precision_constant)
13767 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13777 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13778 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13779 LikelySourceRange->Width == TargetRange.Width))) {
13783 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13785 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13789 unsigned DiagID = diag::warn_impcast_integer_sign;
13797 DiagID = diag::warn_impcast_integer_sign_conditional;
13809 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_int_to_enum);
13814 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13816 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13817 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13818 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13819 TargetEnum->getDecl()->hasNameForLinkage() &&
13820 SourceEnum != TargetEnum) {
13825 diag::warn_impcast_different_enum_types);
13839 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13852 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13853 TrueExpr = BCO->getCommon();
13855 bool Suspicious =
false;
13859 if (T->isBooleanType())
13864 if (!Suspicious)
return;
13867 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13872 if (E->
getType() == T)
return;
13874 Suspicious =
false;
13879 E->
getType(), CC, &Suspicious);
13896struct AnalyzeImplicitConversionsWorkItem {
13905 bool ExtraCheckForImplicitConversion,
13908 WorkList.push_back({E, CC,
false});
13910 if (ExtraCheckForImplicitConversion && E->
getType() != T)
13917 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13919 Expr *OrigE = Item.E;
13938 Expr *SourceExpr = E;
13943 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13944 if (
auto *Src = OVE->getSourceExpr())
13947 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13948 if (UO->getOpcode() == UO_Not &&
13949 UO->getSubExpr()->isKnownToHaveBooleanValue())
13950 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13954 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13955 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13956 BO->getLHS()->isKnownToHaveBooleanValue() &&
13957 BO->getRHS()->isKnownToHaveBooleanValue() &&
13958 BO->getLHS()->HasSideEffects(S.
Context) &&
13959 BO->getRHS()->HasSideEffects(S.
Context)) {
13970 if (SR.str() ==
"&" || SR.str() ==
"|") {
13972 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13973 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13976 BO->getOperatorLoc(),
13977 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13978 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13980 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13998 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
14004 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
14010 if (SourceExpr->
getType() != T)
14019 for (
auto *SE : POE->semantics())
14020 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
14021 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
14025 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
14026 E = CE->getSubExpr();
14032 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
14033 if (InitListE->getNumInits() == 1) {
14034 E = InitListE->getInit(0);
14041 WorkList.push_back({E, CC, IsListInit});
14045 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
14046 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
14050 if (OutArgE->isInOut())
14051 WorkList.push_back(
14052 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14053 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14059 if (BO->isComparisonOp())
14063 if (BO->getOpcode() == BO_Assign)
14066 if (BO->isAssignmentOp())
14082 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14084 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14088 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14089 if (ChildExpr == CSE->getOperand())
14095 if (IsLogicalAndOperator &&
14100 WorkList.push_back({ChildExpr, CC, IsListInit});
14114 if (
U->getOpcode() == UO_LNot) {
14116 }
else if (
U->getOpcode() != UO_AddrOf) {
14117 if (
U->getSubExpr()->getType()->isAtomicType())
14118 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14119 diag::warn_atomic_implicit_seq_cst);
14130 WorkList.push_back({OrigE, CC, IsListInit});
14131 while (!WorkList.empty())
14143 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14146 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14147 if (!M->getMemberDecl()->getType()->isReferenceType())
14149 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14150 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14152 FD =
Call->getDirectCallee();
14161 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14175 if (
SM.isMacroBodyExpansion(Loc))
14177 Loc =
SM.getImmediateMacroCallerLoc(Loc);
14201 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14202 : diag::warn_this_bool_conversion;
14207 bool IsAddressOf =
false;
14209 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14210 if (UO->getOpcode() != UO_AddrOf)
14212 IsAddressOf =
true;
14213 E = UO->getSubExpr();
14217 unsigned DiagID = IsCompare
14218 ? diag::warn_address_of_reference_null_compare
14219 : diag::warn_address_of_reference_bool_conversion;
14227 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14230 llvm::raw_string_ostream S(Str);
14232 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14233 : diag::warn_cast_nonnull_to_bool;
14236 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14241 if (
auto *Callee =
Call->getDirectCallee()) {
14242 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14243 ComplainAboutNonnullParamOrCall(A);
14252 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14253 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14254 MRecordDecl && MRecordDecl->isLambda()) {
14257 << MRecordDecl->getSourceRange() << Range << IsEqual;
14267 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14268 D = M->getMemberDecl();
14276 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14279 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14280 ComplainAboutNonnullParamOrCall(A);
14284 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14288 auto ParamIter = llvm::find(FD->
parameters(), PV);
14290 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14294 ComplainAboutNonnullParamOrCall(
NonNull);
14299 if (ArgNo.getASTIndex() == ParamNo) {
14300 ComplainAboutNonnullParamOrCall(
NonNull);
14311 const bool IsFunctionReference =
14313 if (IsFunctionReference)
14314 T = T->getPointeeType();
14315 const bool IsArray = T->isArrayType();
14316 const bool IsFunction = T->isFunctionType();
14319 if (IsAddressOf && IsFunction) {
14324 if (!IsAddressOf && !IsFunction && !IsArray)
14329 llvm::raw_string_ostream S(Str);
14332 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14333 : diag::warn_impcast_pointer_to_bool;
14340 DiagType = AddressOf;
14341 else if (IsFunction)
14342 DiagType = FunctionPointer;
14344 DiagType = ArrayPointer;
14346 llvm_unreachable(
"Could not determine diagnostic.");
14348 << Range << IsEqual;
14351 if (!IsFunction || IsFunctionReference)
14362 if (ReturnType.
isNull())
14393 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14394 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14396 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14397 Target->isUnsignedIntegerType()) {
14401 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14402 : diag::warn_impcast_overflow_behavior_pedantic;
14406 ? diag::warn_impcast_overflow_behavior_assignment
14407 : diag::warn_impcast_overflow_behavior;
14413 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14414 if (TargetOBT->isWrapKind()) {
14434 CheckArrayAccess(E);
14444void Sema::CheckForIntOverflow (
const Expr *E) {
14446 SmallVector<const Expr *, 2> Exprs(1, E);
14449 const Expr *OriginalE = Exprs.pop_back_val();
14458 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14459 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14462 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14463 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14464 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14466 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14467 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14468 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14469 Exprs.push_back(Temporary->getSubExpr());
14470 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14471 Exprs.push_back(
Array->getIdx());
14472 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14473 Exprs.push_back(Compound->getInitializer());
14474 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14475 New &&
New->isArray()) {
14476 if (
auto ArraySize =
New->getArraySize())
14477 Exprs.push_back(*ArraySize);
14478 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14479 Exprs.push_back(MTE->getSubExpr());
14480 }
while (!Exprs.empty());
14488 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14495 class SequenceTree {
14497 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14498 unsigned Parent : 31;
14499 LLVM_PREFERRED_TYPE(
bool)
14500 unsigned Merged : 1;
14502 SmallVector<Value, 8> Values;
14508 friend class SequenceTree;
14512 explicit Seq(
unsigned N) : Index(N) {}
14515 Seq() : Index(0) {}
14518 SequenceTree() { Values.push_back(
Value(0)); }
14519 Seq root()
const {
return Seq(0); }
14524 Seq allocate(
Seq Parent) {
14525 Values.push_back(
Value(Parent.Index));
14526 return Seq(Values.size() - 1);
14531 Values[S.Index].Merged =
true;
14537 bool isUnsequenced(
Seq Cur,
Seq Old) {
14538 unsigned C = representative(Cur.Index);
14539 unsigned Target = representative(Old.Index);
14543 C = Values[
C].Parent;
14550 unsigned representative(
unsigned K) {
14551 if (Values[K].Merged)
14553 return Values[K].Parent = representative(Values[K].Parent);
14559 using Object =
const NamedDecl *;
14573 UK_ModAsSideEffect,
14575 UK_Count = UK_ModAsSideEffect + 1
14581 const Expr *UsageExpr =
nullptr;
14582 SequenceTree::Seq
Seq;
14588 Usage Uses[UK_Count];
14591 bool Diagnosed =
false;
14595 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14603 UsageInfoMap UsageMap;
14606 SequenceTree::Seq Region;
14610 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14614 SmallVectorImpl<const Expr *> &WorkList;
14621 struct SequencedSubexpression {
14622 SequencedSubexpression(SequenceChecker &
Self)
14623 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14624 Self.ModAsSideEffect = &ModAsSideEffect;
14627 ~SequencedSubexpression() {
14628 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14632 UsageInfo &UI =
Self.UsageMap[M.first];
14633 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14634 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14635 SideEffectUsage = M.second;
14637 Self.ModAsSideEffect = OldModAsSideEffect;
14640 SequenceChecker &
Self;
14641 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14642 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14649 class EvaluationTracker {
14651 EvaluationTracker(SequenceChecker &
Self)
14653 Self.EvalTracker =
this;
14656 ~EvaluationTracker() {
14657 Self.EvalTracker = Prev;
14659 Prev->EvalOK &= EvalOK;
14662 bool evaluate(
const Expr *E,
bool &
Result) {
14667 Self.SemaRef.isConstantEvaluatedContext());
14672 SequenceChecker &
Self;
14673 EvaluationTracker *Prev;
14674 bool EvalOK =
true;
14675 } *EvalTracker =
nullptr;
14679 Object getObject(
const Expr *E,
bool Mod)
const {
14681 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14682 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14683 return getObject(UO->getSubExpr(), Mod);
14684 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14685 if (BO->getOpcode() == BO_Comma)
14686 return getObject(BO->getRHS(), Mod);
14687 if (Mod && BO->isAssignmentOp())
14688 return getObject(BO->getLHS(), Mod);
14689 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14692 return ME->getMemberDecl();
14693 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14702 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14704 Usage &U = UI.Uses[UK];
14705 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14709 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14710 ModAsSideEffect->push_back(std::make_pair(O, U));
14712 U.UsageExpr = UsageExpr;
14722 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14723 UsageKind OtherKind,
bool IsModMod) {
14727 const Usage &U = UI.Uses[OtherKind];
14728 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14731 const Expr *Mod = U.UsageExpr;
14732 const Expr *ModOrUse = UsageExpr;
14733 if (OtherKind == UK_Use)
14734 std::swap(Mod, ModOrUse);
14738 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14739 : diag::warn_unsequenced_mod_use)
14740 << O << SourceRange(ModOrUse->
getExprLoc()));
14741 UI.Diagnosed =
true;
14770 void notePreUse(
Object O,
const Expr *UseExpr) {
14771 UsageInfo &UI = UsageMap[O];
14773 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14776 void notePostUse(
Object O,
const Expr *UseExpr) {
14777 UsageInfo &UI = UsageMap[O];
14778 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14780 addUsage(O, UI, UseExpr, UK_Use);
14783 void notePreMod(
Object O,
const Expr *ModExpr) {
14784 UsageInfo &UI = UsageMap[O];
14786 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14787 checkUsage(O, UI, ModExpr, UK_Use,
false);
14790 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14791 UsageInfo &UI = UsageMap[O];
14792 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14794 addUsage(O, UI, ModExpr, UK);
14798 SequenceChecker(Sema &S,
const Expr *E,
14799 SmallVectorImpl<const Expr *> &WorkList)
14800 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14804 (void)this->WorkList;
14807 void VisitStmt(
const Stmt *S) {
14811 void VisitExpr(
const Expr *E) {
14813 Base::VisitStmt(E);
14816 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14817 for (
auto *Sub : CSE->
children()) {
14818 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14833 void VisitCastExpr(
const CastExpr *E) {
14845 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14846 const Expr *SequencedAfter) {
14847 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14848 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14849 SequenceTree::Seq OldRegion = Region;
14852 SequencedSubexpression SeqBefore(*
this);
14853 Region = BeforeRegion;
14854 Visit(SequencedBefore);
14857 Region = AfterRegion;
14858 Visit(SequencedAfter);
14860 Region = OldRegion;
14862 Tree.merge(BeforeRegion);
14863 Tree.merge(AfterRegion);
14866 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14871 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14878 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14879 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14880 void VisitBinPtrMem(
const BinaryOperator *BO) {
14885 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14892 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14893 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14894 void VisitBinShlShr(
const BinaryOperator *BO) {
14898 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14905 void VisitBinComma(
const BinaryOperator *BO) {
14910 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14913 void VisitBinAssign(
const BinaryOperator *BO) {
14914 SequenceTree::Seq RHSRegion;
14915 SequenceTree::Seq LHSRegion;
14917 RHSRegion = Tree.allocate(Region);
14918 LHSRegion = Tree.allocate(Region);
14920 RHSRegion = Region;
14921 LHSRegion = Region;
14923 SequenceTree::Seq OldRegion = Region;
14939 SequencedSubexpression SeqBefore(*
this);
14940 Region = RHSRegion;
14944 Region = LHSRegion;
14948 notePostUse(O, BO);
14952 Region = LHSRegion;
14956 notePostUse(O, BO);
14958 Region = RHSRegion;
14966 Region = OldRegion;
14970 : UK_ModAsSideEffect);
14972 Tree.merge(RHSRegion);
14973 Tree.merge(LHSRegion);
14977 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14978 VisitBinAssign(CAO);
14981 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14982 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14983 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14986 return VisitExpr(UO);
14994 : UK_ModAsSideEffect);
14997 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14998 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14999 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
15002 return VisitExpr(UO);
15006 notePostMod(O, UO, UK_ModAsSideEffect);
15009 void VisitBinLOr(
const BinaryOperator *BO) {
15015 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15016 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15017 SequenceTree::Seq OldRegion = Region;
15019 EvaluationTracker Eval(*
this);
15021 SequencedSubexpression Sequenced(*
this);
15022 Region = LHSRegion;
15029 bool EvalResult =
false;
15030 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15031 bool ShouldVisitRHS = !EvalOK || !EvalResult;
15032 if (ShouldVisitRHS) {
15033 Region = RHSRegion;
15037 Region = OldRegion;
15038 Tree.merge(LHSRegion);
15039 Tree.merge(RHSRegion);
15042 void VisitBinLAnd(
const BinaryOperator *BO) {
15048 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15049 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15050 SequenceTree::Seq OldRegion = Region;
15052 EvaluationTracker Eval(*
this);
15054 SequencedSubexpression Sequenced(*
this);
15055 Region = LHSRegion;
15061 bool EvalResult =
false;
15062 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15063 bool ShouldVisitRHS = !EvalOK || EvalResult;
15064 if (ShouldVisitRHS) {
15065 Region = RHSRegion;
15069 Region = OldRegion;
15070 Tree.merge(LHSRegion);
15071 Tree.merge(RHSRegion);
15074 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15079 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15095 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15096 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15097 SequenceTree::Seq OldRegion = Region;
15099 EvaluationTracker Eval(*
this);
15101 SequencedSubexpression Sequenced(*
this);
15102 Region = ConditionRegion;
15112 bool EvalResult =
false;
15113 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15114 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15115 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15116 if (ShouldVisitTrueExpr) {
15117 Region = TrueRegion;
15120 if (ShouldVisitFalseExpr) {
15121 Region = FalseRegion;
15125 Region = OldRegion;
15126 Tree.merge(ConditionRegion);
15127 Tree.merge(TrueRegion);
15128 Tree.merge(FalseRegion);
15131 void VisitCallExpr(
const CallExpr *CE) {
15143 SequencedSubexpression Sequenced(*
this);
15148 SequenceTree::Seq CalleeRegion;
15149 SequenceTree::Seq OtherRegion;
15150 if (SemaRef.getLangOpts().CPlusPlus17) {
15151 CalleeRegion = Tree.allocate(Region);
15152 OtherRegion = Tree.allocate(Region);
15154 CalleeRegion = Region;
15155 OtherRegion = Region;
15157 SequenceTree::Seq OldRegion = Region;
15160 Region = CalleeRegion;
15162 SequencedSubexpression Sequenced(*this);
15163 Visit(CE->getCallee());
15165 Visit(CE->getCallee());
15169 Region = OtherRegion;
15173 Region = OldRegion;
15175 Tree.merge(CalleeRegion);
15176 Tree.merge(OtherRegion);
15194 return VisitCallExpr(CXXOCE);
15205 case OO_MinusEqual:
15207 case OO_SlashEqual:
15208 case OO_PercentEqual:
15209 case OO_CaretEqual:
15212 case OO_LessLessEqual:
15213 case OO_GreaterGreaterEqual:
15214 SequencingKind = RHSBeforeLHS;
15218 case OO_GreaterGreater:
15224 SequencingKind = LHSBeforeRHS;
15228 SequencingKind = LHSBeforeRest;
15232 SequencingKind = NoSequencing;
15236 if (SequencingKind == NoSequencing)
15237 return VisitCallExpr(CXXOCE);
15240 SequencedSubexpression Sequenced(*
this);
15243 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15244 "Should only get there with C++17 and above!");
15245 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15246 "Should only get there with an overloaded binary operator"
15247 " or an overloaded call operator!");
15249 if (SequencingKind == LHSBeforeRest) {
15250 assert(CXXOCE->getOperator() == OO_Call &&
15251 "We should only have an overloaded call operator here!");
15260 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15261 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15262 SequenceTree::Seq OldRegion = Region;
15264 assert(CXXOCE->getNumArgs() >= 1 &&
15265 "An overloaded call operator must have at least one argument"
15266 " for the postfix-expression!");
15267 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15268 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15269 CXXOCE->getNumArgs() - 1);
15273 Region = PostfixExprRegion;
15274 SequencedSubexpression Sequenced(*this);
15275 Visit(PostfixExpr);
15279 Region = ArgsRegion;
15280 for (const Expr *Arg : Args)
15283 Region = OldRegion;
15284 Tree.merge(PostfixExprRegion);
15285 Tree.merge(ArgsRegion);
15287 assert(CXXOCE->getNumArgs() == 2 &&
15288 "Should only have two arguments here!");
15289 assert((SequencingKind == LHSBeforeRHS ||
15290 SequencingKind == RHSBeforeLHS) &&
15291 "Unexpected sequencing kind!");
15295 const Expr *E1 = CXXOCE->getArg(0);
15296 const Expr *E2 = CXXOCE->getArg(1);
15297 if (SequencingKind == RHSBeforeLHS)
15300 return VisitSequencedExpressions(E1, E2);
15307 SequencedSubexpression Sequenced(*
this);
15310 return VisitExpr(CCE);
15313 SequenceExpressionsInOrder(
15319 return VisitExpr(ILE);
15322 SequenceExpressionsInOrder(ILE->
inits());
15334 SequenceTree::Seq Parent = Region;
15335 for (
const Expr *E : ExpressionList) {
15338 Region = Tree.allocate(Parent);
15339 Elts.push_back(Region);
15345 for (
unsigned I = 0; I < Elts.size(); ++I)
15346 Tree.merge(Elts[I]);
15350SequenceChecker::UsageInfo::UsageInfo() =
default;
15354void Sema::CheckUnsequencedOperations(
const Expr *E) {
15355 SmallVector<const Expr *, 8> WorkList;
15356 WorkList.push_back(E);
15357 while (!WorkList.empty()) {
15358 const Expr *Item = WorkList.pop_back_val();
15359 SequenceChecker(*
this, Item, WorkList);
15364 bool IsConstexpr) {
15367 CheckImplicitConversions(E, CheckLoc);
15369 CheckUnsequencedOperations(E);
15371 CheckForIntOverflow(E);
15384 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15388 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15392 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15406 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15410 bool CheckParameterNames) {
15411 bool HasInvalidParm =
false;
15413 assert(Param &&
"null in a parameter list");
15422 if (!Param->isInvalidDecl() &&
15424 diag::err_typecheck_decl_incomplete_type) ||
15426 diag::err_abstract_type_in_decl,
15428 Param->setInvalidDecl();
15429 HasInvalidParm =
true;
15434 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15438 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15446 QualType PType = Param->getOriginalType();
15454 if (!Param->isInvalidDecl()) {
15455 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15456 if (!ClassDecl->isInvalidDecl() &&
15457 !ClassDecl->hasIrrelevantDestructor() &&
15458 !ClassDecl->isDependentContext() &&
15459 ClassDecl->isParamDestroyedInCallee()) {
15471 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15472 if (!Param->getType().isConstQualified())
15473 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15477 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15482 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15483 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15488 if (!Param->isInvalidDecl() &&
15489 Param->getOriginalType()->isWebAssemblyTableType()) {
15490 Param->setInvalidDecl();
15491 HasInvalidParm =
true;
15492 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15496 return HasInvalidParm;
15499std::optional<std::pair<
15508static std::pair<CharUnits, CharUnits>
15516 if (
Base->isVirtual()) {
15523 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15530 DerivedType =
Base->getType();
15533 return std::make_pair(BaseAlignment, Offset);
15537static std::optional<std::pair<CharUnits, CharUnits>>
15543 return std::nullopt;
15548 return std::nullopt;
15552 CharUnits Offset = EltSize * IdxRes->getExtValue();
15555 return std::make_pair(P->first, P->second + Offset);
15561 return std::make_pair(
15562 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15568std::optional<std::pair<
15576 case Stmt::CStyleCastExprClass:
15577 case Stmt::CXXStaticCastExprClass:
15578 case Stmt::ImplicitCastExprClass: {
15580 const Expr *From = CE->getSubExpr();
15581 switch (CE->getCastKind()) {
15586 case CK_UncheckedDerivedToBase:
15587 case CK_DerivedToBase: {
15597 case Stmt::ArraySubscriptExprClass: {
15602 case Stmt::DeclRefExprClass: {
15606 if (!VD->getType()->isReferenceType()) {
15608 if (VD->hasDependentAlignment())
15617 case Stmt::MemberExprClass: {
15619 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15623 std::optional<std::pair<CharUnits, CharUnits>> P;
15632 return std::make_pair(P->first,
15635 case Stmt::UnaryOperatorClass: {
15645 case Stmt::BinaryOperatorClass: {
15657 return std::nullopt;
15662std::optional<std::pair<
15671 case Stmt::CStyleCastExprClass:
15672 case Stmt::CXXStaticCastExprClass:
15673 case Stmt::ImplicitCastExprClass: {
15675 const Expr *From = CE->getSubExpr();
15676 switch (CE->getCastKind()) {
15681 case CK_ArrayToPointerDecay:
15683 case CK_UncheckedDerivedToBase:
15684 case CK_DerivedToBase: {
15694 case Stmt::CXXThisExprClass: {
15699 case Stmt::UnaryOperatorClass: {
15705 case Stmt::BinaryOperatorClass: {
15714 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15715 std::swap(LHS, RHS);
15725 return std::nullopt;
15730 std::optional<std::pair<CharUnits, CharUnits>> P =
15734 return P->first.alignmentAtOffset(P->second);
15752 if (!DestPtr)
return;
15758 if (DestAlign.
isOne())
return;
15762 if (!SrcPtr)
return;
15773 if (SrcAlign >= DestAlign)
return;
15778 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15782void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15784 bool AllowOnePastEnd,
bool IndexNegated) {
15793 const Type *EffectiveType =
15797 Context.getAsConstantArrayType(BaseExpr->
getType());
15800 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15802 const Type *BaseType =
15804 bool IsUnboundedArray =
15806 Context, StrictFlexArraysLevel,
15809 (!IsUnboundedArray && BaseType->isDependentType()))
15817 if (IndexNegated) {
15818 index.setIsUnsigned(
false);
15822 if (IsUnboundedArray) {
15825 if (
index.isUnsigned() || !
index.isNegative()) {
15827 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15829 if (
index.getBitWidth() < AddrBits)
15831 std::optional<CharUnits> ElemCharUnits =
15832 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15835 if (!ElemCharUnits || ElemCharUnits->isZero())
15837 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15842 if (
index.getActiveBits() <= AddrBits) {
15844 llvm::APInt Product(
index);
15846 Product = Product.umul_ov(ElemBytes, Overflow);
15847 if (!Overflow && Product.getActiveBits() <= AddrBits)
15853 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15854 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15856 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15857 MaxElems = MaxElems.udiv(ElemBytes);
15860 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15861 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15866 PDiag(DiagID) << index << AddrBits
15867 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15868 << ElemBytes << MaxElems
15869 << MaxElems.getZExtValue()
15872 const NamedDecl *ND =
nullptr;
15874 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15876 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15878 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15879 ND = ME->getMemberDecl();
15883 PDiag(diag::note_array_declared_here) << ND);
15888 if (index.isUnsigned() || !index.isNegative()) {
15898 llvm::APInt size = ArrayTy->
getSize();
15900 if (BaseType != EffectiveType) {
15908 if (!ptrarith_typesize)
15909 ptrarith_typesize =
Context.getCharWidth();
15911 if (ptrarith_typesize != array_typesize) {
15913 uint64_t ratio = array_typesize / ptrarith_typesize;
15917 if (ptrarith_typesize * ratio == array_typesize)
15918 size *= llvm::APInt(size.getBitWidth(), ratio);
15922 if (size.getBitWidth() > index.getBitWidth())
15923 index = index.zext(size.getBitWidth());
15924 else if (size.getBitWidth() < index.getBitWidth())
15925 size = size.zext(index.getBitWidth());
15931 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15938 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15940 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15941 SourceLocation IndexLoc =
15943 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15948 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15949 : diag::warn_ptr_arith_exceeds_bounds;
15950 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15951 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15955 << index << ArrayTy->
desugar() << CastMsg
15958 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15960 DiagID = diag::warn_ptr_arith_precedes_bounds;
15961 if (index.isNegative()) index = -index;
15968 const NamedDecl *ND =
nullptr;
15970 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15972 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15974 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15975 ND = ME->getMemberDecl();
15979 PDiag(diag::note_array_declared_here) << ND);
15982void Sema::CheckArrayAccess(
const Expr *
expr) {
15983 int AllowOnePastEnd = 0;
15985 expr =
expr->IgnoreParenImpCasts();
15986 switch (
expr->getStmtClass()) {
15987 case Stmt::ArraySubscriptExprClass: {
15990 AllowOnePastEnd > 0);
15994 case Stmt::MemberExprClass: {
15998 case Stmt::CXXMemberCallExprClass: {
16002 case Stmt::ArraySectionExprClass: {
16008 nullptr, AllowOnePastEnd > 0);
16011 case Stmt::UnaryOperatorClass: {
16027 case Stmt::ConditionalOperatorClass: {
16029 if (
const Expr *lhs = cond->
getLHS())
16030 CheckArrayAccess(lhs);
16031 if (
const Expr *rhs = cond->
getRHS())
16032 CheckArrayAccess(rhs);
16035 case Stmt::CXXOperatorCallExprClass: {
16037 for (
const auto *Arg : OCE->arguments())
16038 CheckArrayAccess(Arg);
16048 Expr *RHS,
bool isProperty) {
16060 S.
Diag(Loc, diag::warn_arc_literal_assign)
16062 << (isProperty ? 0 : 1)
16070 Expr *RHS,
bool isProperty) {
16073 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16074 S.
Diag(Loc, diag::warn_arc_retained_assign)
16076 << (isProperty ? 0 : 1)
16080 RHS =
cast->getSubExpr();
16122 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16151 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16152 Diag(Loc, diag::warn_arc_retained_property_assign)
16156 RHS =
cast->getSubExpr();
16179 bool StmtLineInvalid;
16180 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16182 if (StmtLineInvalid)
16185 bool BodyLineInvalid;
16186 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16188 if (BodyLineInvalid)
16192 if (StmtLine != BodyLine)
16207 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16216 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16220 const Stmt *PossibleBody) {
16226 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16227 StmtLoc = FS->getRParenLoc();
16228 Body = FS->getBody();
16229 DiagID = diag::warn_empty_for_body;
16230 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16231 StmtLoc = WS->getRParenLoc();
16232 Body = WS->getBody();
16233 DiagID = diag::warn_empty_while_body;
16238 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16262 if (!ProbableTypo) {
16263 bool BodyColInvalid;
16264 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16266 if (BodyColInvalid)
16269 bool StmtColInvalid;
16272 if (StmtColInvalid)
16275 if (BodyCol > StmtCol)
16276 ProbableTypo =
true;
16279 if (ProbableTypo) {
16281 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16289 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16301 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16303 RHSExpr = CE->
getArg(0);
16304 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16305 CXXSCE && CXXSCE->isXValue())
16306 RHSExpr = CXXSCE->getSubExpr();
16310 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16311 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16314 if (LHSDeclRef && RHSDeclRef) {
16321 auto D =
Diag(OpLoc, diag::warn_self_move)
16337 const Expr *LHSBase = LHSExpr;
16338 const Expr *RHSBase = RHSExpr;
16339 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16340 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16341 if (!LHSME || !RHSME)
16344 while (LHSME && RHSME) {
16351 LHSME = dyn_cast<MemberExpr>(LHSBase);
16352 RHSME = dyn_cast<MemberExpr>(RHSBase);
16355 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16356 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16357 if (LHSDeclRef && RHSDeclRef) {
16364 Diag(OpLoc, diag::warn_self_move)
16371 Diag(OpLoc, diag::warn_self_move)
16395 bool AreUnionMembers =
false) {
16399 assert(((Field1Parent->isStructureOrClassType() &&
16400 Field2Parent->isStructureOrClassType()) ||
16401 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16402 "Can't evaluate layout compatibility between a struct field and a "
16404 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16405 (AreUnionMembers && Field1Parent->isUnionType())) &&
16406 "AreUnionMembers should be 'true' for union fields (only).");
16420 if (Bits1 != Bits2)
16424 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16425 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16428 if (!AreUnionMembers &&
16440 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16441 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16443 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16444 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16449 return isLayoutCompatible(C, F1, F2);
16460 for (
auto *Field1 : RD1->
fields()) {
16461 auto I = UnmatchedFields.begin();
16462 auto E = UnmatchedFields.end();
16464 for ( ; I != E; ++I) {
16466 bool Result = UnmatchedFields.erase(*I);
16476 return UnmatchedFields.empty();
16502 if (
C.hasSameType(T1, T2))
16511 if (TC1 == Type::Enum)
16513 if (TC1 == Type::Record) {
16532 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16563 const ValueDecl **VD, uint64_t *MagicValue,
16564 bool isConstantEvaluated) {
16572 case Stmt::UnaryOperatorClass: {
16581 case Stmt::DeclRefExprClass: {
16587 case Stmt::IntegerLiteralClass: {
16589 llvm::APInt MagicValueAPInt = IL->
getValue();
16590 if (MagicValueAPInt.getActiveBits() <= 64) {
16591 *MagicValue = MagicValueAPInt.getZExtValue();
16597 case Stmt::BinaryConditionalOperatorClass:
16598 case Stmt::ConditionalOperatorClass: {
16603 isConstantEvaluated)) {
16613 case Stmt::BinaryOperatorClass: {
16616 TypeExpr = BO->
getRHS();
16646 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16649 bool isConstantEvaluated) {
16650 FoundWrongKind =
false;
16655 uint64_t MagicValue;
16657 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16661 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16662 if (I->getArgumentKind() != ArgumentKind) {
16663 FoundWrongKind =
true;
16666 TypeInfo.Type = I->getMatchingCType();
16667 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16668 TypeInfo.MustBeNull = I->getMustBeNull();
16679 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16680 if (I == MagicValues->end())
16689 bool LayoutCompatible,
16691 if (!TypeTagForDatatypeMagicValues)
16692 TypeTagForDatatypeMagicValues.reset(
16693 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16696 (*TypeTagForDatatypeMagicValues)[Magic] =
16712 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16713 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16714 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16715 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16718void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16721 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16722 bool IsPointerAttr = Attr->getIsPointer();
16725 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16726 if (TypeTagIdxAST >= ExprArgs.size()) {
16727 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16728 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16731 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16732 bool FoundWrongKind;
16735 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16737 if (FoundWrongKind)
16739 diag::warn_type_tag_for_datatype_wrong_kind)
16745 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16746 if (ArgumentIdxAST >= ExprArgs.size()) {
16747 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16748 << 1 << Attr->getArgumentIdx().getSourceIndex();
16751 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16752 if (IsPointerAttr) {
16754 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16755 if (ICE->getType()->isVoidPointerType() &&
16756 ICE->getCastKind() == CK_BitCast)
16757 ArgumentExpr = ICE->getSubExpr();
16759 QualType ArgumentType = ArgumentExpr->
getType();
16765 if (TypeInfo.MustBeNull) {
16770 diag::warn_type_safety_null_pointer_required)
16778 QualType RequiredType = TypeInfo.Type;
16780 RequiredType =
Context.getPointerType(RequiredType);
16782 bool mismatch =
false;
16783 if (!TypeInfo.LayoutCompatible) {
16784 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16805 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16806 << ArgumentType << ArgumentKind
16807 << TypeInfo.LayoutCompatible << RequiredType
16825 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16833 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
16839 auto &MisalignedMembersForExpr =
16841 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16842 if (MA != MisalignedMembersForExpr.end() &&
16843 (T->isDependentType() || T->isIntegerType() ||
16844 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
16846 T->getPointeeType()) <= MA->Alignment))))
16847 MisalignedMembersForExpr.erase(MA);
16856 const auto *ME = dyn_cast<MemberExpr>(E);
16868 bool AnyIsPacked =
false;
16870 QualType BaseType = ME->getBase()->getType();
16871 if (BaseType->isDependentType())
16875 auto *RD = BaseType->castAsRecordDecl();
16880 auto *FD = dyn_cast<FieldDecl>(MD);
16886 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16887 ReverseMemberChain.push_back(FD);
16890 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16892 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16899 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16910 if (ExpectedAlignment.
isOne())
16915 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16916 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16920 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16924 if (DRE && !TopME->
isArrow()) {
16927 CompleteObjectAlignment =
16928 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16932 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16935 CompleteObjectAlignment < ExpectedAlignment) {
16946 for (
FieldDecl *FDI : ReverseMemberChain) {
16947 if (FDI->hasAttr<PackedAttr>() ||
16948 FDI->getParent()->hasAttr<PackedAttr>()) {
16950 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16956 assert(FD &&
"We did not find a packed FieldDecl!");
16957 Action(E, FD->
getParent(), FD, Alignment);
16961void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16962 using namespace std::placeholders;
16965 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16989bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16990 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
17017 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
17034 assert(!Args.empty() &&
"Should have at least one argument.");
17036 Expr *Arg0 = Args.front();
17039 auto EmitError = [&](
Expr *ArgI) {
17041 diag::err_typecheck_call_different_arg_types)
17042 << Arg0->
getType() << ArgI->getType();
17047 for (
Expr *ArgI : Args.drop_front())
17058 for (
Expr *ArgI : Args.drop_front()) {
17059 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17062 VecI->getElementType()) ||
17063 Vec0->getNumElements() != VecI->getNumElements()) {
17072std::optional<QualType>
17076 return std::nullopt;
17080 return std::nullopt;
17083 for (
int I = 0; I < 2; ++I) {
17087 return std::nullopt;
17088 Args[I] = Converted.
get();
17095 return std::nullopt;
17098 return std::nullopt;
17100 TheCall->
setArg(0, Args[0]);
17101 TheCall->
setArg(1, Args[1]);
17112 TheCall->
getArg(1), Loc) ||
17114 TheCall->
getArg(2), Loc))
17118 for (
int I = 0; I < 3; ++I) {
17123 Args[I] = Converted.
get();
17126 int ArgOrdinal = 1;
17127 for (
Expr *Arg : Args) {
17129 ArgTyRestr, ArgOrdinal++))
17136 for (
int I = 0; I < 3; ++I)
17137 TheCall->
setArg(I, Args[I]);
17143bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17155bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17164 diag::err_builtin_invalid_arg_type)
17165 << 1 << 2 << 1 << 1 << TyArg;
17179 Expr *Matrix = MatrixArg.
get();
17181 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17184 << 1 << 3 << 0 << 0
17191 QualType ResultType =
Context.getConstantMatrixType(
17192 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17195 TheCall->
setType(ResultType);
17198 TheCall->
setArg(0, Matrix);
17203static std::optional<unsigned>
17211 uint64_t
Dim =
Value->getZExtValue();
17227 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17229 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17237 unsigned PtrArgIdx = 0;
17238 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17239 Expr *RowsExpr = TheCall->
getArg(1);
17240 Expr *ColumnsExpr = TheCall->
getArg(2);
17241 Expr *StrideExpr = TheCall->
getArg(3);
17243 bool ArgError =
false;
17250 PtrExpr = PtrConv.
get();
17251 TheCall->
setArg(0, PtrExpr);
17258 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17259 QualType ElementTy;
17262 << PtrArgIdx + 1 << 0 << 5 << 0
17266 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17270 << PtrArgIdx + 1 << 0 << 5
17277 auto ApplyArgumentConversions = [
this](Expr *E) {
17286 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17288 RowsExpr = RowsConv.
get();
17289 TheCall->
setArg(1, RowsExpr);
17291 RowsExpr =
nullptr;
17293 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17295 ColumnsExpr = ColumnsConv.
get();
17296 TheCall->
setArg(2, ColumnsExpr);
17298 ColumnsExpr =
nullptr;
17309 std::optional<unsigned> MaybeRows;
17313 std::optional<unsigned> MaybeColumns;
17318 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17321 StrideExpr = StrideConv.
get();
17322 TheCall->
setArg(3, StrideExpr);
17325 if (std::optional<llvm::APSInt>
Value =
17328 if (Stride < *MaybeRows) {
17330 diag::err_builtin_matrix_stride_too_small);
17336 if (ArgError || !MaybeRows || !MaybeColumns)
17340 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17351 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17353 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17361 unsigned PtrArgIdx = 1;
17362 Expr *MatrixExpr = TheCall->
getArg(0);
17363 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17364 Expr *StrideExpr = TheCall->
getArg(2);
17366 bool ArgError =
false;
17372 MatrixExpr = MatrixConv.
get();
17373 TheCall->
setArg(0, MatrixExpr);
17380 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17383 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17391 PtrExpr = PtrConv.
get();
17392 TheCall->
setArg(1, PtrExpr);
17400 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17403 << PtrArgIdx + 1 << 0 << 5 << 0
17407 QualType ElementTy = PtrTy->getPointeeType();
17409 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17414 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17416 diag::err_builtin_matrix_pointer_arg_mismatch)
17417 << ElementTy << MatrixTy->getElementType();
17432 StrideExpr = StrideConv.
get();
17433 TheCall->
setArg(2, StrideExpr);
17438 if (std::optional<llvm::APSInt>
Value =
17441 if (Stride < MatrixTy->getNumRows()) {
17443 diag::err_builtin_matrix_stride_too_small);
17463 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17468 llvm::StringSet<> CalleeTCBs;
17469 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17470 CalleeTCBs.insert(A->getTCBName());
17471 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17472 CalleeTCBs.insert(A->getTCBName());
17476 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17477 StringRef CallerTCB = A->getTCBName();
17478 if (CalleeTCBs.count(CallerTCB) == 0) {
17479 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17480 << 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 isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
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 isAnyComplexType() 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.