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);
559 return getStringLiteral(
T.getAsString(Policy));
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));
1152class FortifiedBufferChecker {
1154 FortifiedBufferChecker(Sema &S, FunctionDecl *FD, CallExpr *TheCall)
1155 : S(S), TheCall(TheCall), FD(FD),
1156 DABAttr(FD ? FD->getAttr<DiagnoseAsBuiltinAttr>() :
nullptr) {
1161 std::optional<unsigned> TranslateIndex(
unsigned Index) {
1168 unsigned DABIndices = DABAttr->argIndices_size();
1169 unsigned NewIndex = Index < DABIndices
1170 ? DABAttr->argIndices_begin()[Index]
1173 return std::nullopt;
1177 std::optional<llvm::APSInt>
1178 ComputeExplicitObjectSizeArgument(
unsigned Index) {
1179 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1181 return std::nullopt;
1182 unsigned NewIndex = *IndexOptional;
1184 Expr *SizeArg = TheCall->
getArg(NewIndex);
1186 return std::nullopt;
1188 assert(
Integer.isUnsigned() &&
1189 "size arg should be unsigned after implicit conversion to size_t");
1193 std::optional<llvm::APSInt> ComputeSizeArgument(
unsigned Index) {
1199 if (Index < FD->getNumParams()) {
1200 if (
const auto *POS =
1202 BOSType = POS->getType();
1205 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1207 return std::nullopt;
1208 unsigned NewIndex = *IndexOptional;
1211 return std::nullopt;
1213 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1214 if (std::optional<uint64_t> ObjSize =
1217 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1219 return std::nullopt;
1222 std::optional<llvm::APSInt> ComputeStrLenArgument(
unsigned Index) {
1223 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1225 return std::nullopt;
1226 unsigned NewIndex = *IndexOptional;
1228 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1230 if (std::optional<uint64_t>
Result =
1233 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1235 return std::nullopt;
1238 unsigned getSizeTypeWidth()
const {
return SizeTypeWidth; }
1240 unsigned getBuiltinID()
const {
1241 const FunctionDecl *UseDecl = FD;
1243 UseDecl = DABAttr->getFunction();
1244 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1251 unsigned ID = getBuiltinID();
1255 assert(Callee &&
"expected callee");
1256 return Callee->getName().str();
1259 StringRef Ref = Name;
1261 if (!(Ref.consume_front(
"__builtin___") && Ref.consume_back(
"_chk")))
1262 Ref.consume_front(
"__builtin_");
1263 assert(!Ref.empty() &&
"expected non-empty function name");
1268 void checkSourceOverread(
unsigned SrcArgIdx,
unsigned SizeArgIdx) {
1272 const Expr *SrcArg = TheCall->
getArg(SrcArgIdx);
1273 const Expr *SizeArg = TheCall->
getArg(SizeArgIdx);
1278 std::optional<llvm::APSInt> CopyLen =
1279 ComputeExplicitObjectSizeArgument(SizeArgIdx);
1280 std::optional<llvm::APSInt> SrcBufSize = ComputeSizeArgument(SrcArgIdx);
1282 if (!CopyLen || !SrcBufSize)
1286 if (llvm::APSInt::compareValues(*CopyLen, *SrcBufSize) <= 0)
1290 S.
PDiag(diag::warn_stringop_overread)
1292 << SrcBufSize->getZExtValue());
1299 const DiagnoseAsBuiltinAttr *DABAttr;
1300 unsigned SizeTypeWidth;
1304void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1309 FortifiedBufferChecker Checker(*
this, FD, TheCall);
1311 unsigned BuiltinID = Checker.getBuiltinID();
1315 unsigned SizeTypeWidth = Checker.getSizeTypeWidth();
1317 std::optional<llvm::APSInt> SourceSize;
1318 std::optional<llvm::APSInt> DestinationSize;
1319 unsigned DiagID = 0;
1321 switch (BuiltinID) {
1324 case Builtin::BI__builtin_strcat:
1325 case Builtin::BIstrcat:
1326 case Builtin::BI__builtin_stpcpy:
1327 case Builtin::BIstpcpy:
1328 case Builtin::BI__builtin_strcpy:
1329 case Builtin::BIstrcpy: {
1330 DiagID = diag::warn_fortify_strlen_overflow;
1331 SourceSize = Checker.ComputeStrLenArgument(1);
1332 DestinationSize = Checker.ComputeSizeArgument(0);
1336 case Builtin::BI__builtin___strcat_chk:
1337 case Builtin::BI__builtin___stpcpy_chk:
1338 case Builtin::BI__builtin___strcpy_chk: {
1339 DiagID = diag::warn_fortify_strlen_overflow;
1340 SourceSize = Checker.ComputeStrLenArgument(1);
1341 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1345 case Builtin::BIscanf:
1346 case Builtin::BIfscanf:
1347 case Builtin::BIsscanf: {
1348 unsigned FormatIndex = 1;
1349 unsigned DataIndex = 2;
1350 if (BuiltinID == Builtin::BIscanf) {
1355 const auto *FormatExpr =
1358 StringRef FormatStrRef;
1363 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1364 unsigned SourceSize) {
1365 DiagID = diag::warn_fortify_scanf_overflow;
1366 unsigned Index = ArgIndex + DataIndex;
1367 std::string FunctionName = Checker.getFunctionName();
1369 PDiag(DiagID) << FunctionName << (Index + 1)
1370 << DestSize << SourceSize);
1373 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1374 return Checker.ComputeSizeArgument(Index + DataIndex);
1376 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1377 const char *FormatBytes = FormatStrRef.data();
1388 case Builtin::BIsprintf:
1389 case Builtin::BI__builtin___sprintf_chk: {
1390 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1393 StringRef FormatStrRef;
1396 EstimateSizeFormatHandler H(FormatStrRef);
1397 const char *FormatBytes = FormatStrRef.data();
1399 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1400 Context.getTargetInfo(),
false)) {
1401 DiagID = H.isKernelCompatible()
1402 ? diag::warn_format_overflow
1403 : diag::warn_format_overflow_non_kprintf;
1404 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1405 .extOrTrunc(SizeTypeWidth);
1406 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1407 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1409 DestinationSize = Checker.ComputeSizeArgument(0);
1416 case Builtin::BI__builtin___memcpy_chk:
1417 case Builtin::BI__builtin___memmove_chk:
1418 case Builtin::BI__builtin___memset_chk:
1419 case Builtin::BI__builtin___strlcat_chk:
1420 case Builtin::BI__builtin___strlcpy_chk:
1421 case Builtin::BI__builtin___strncat_chk:
1422 case Builtin::BI__builtin___strncpy_chk:
1423 case Builtin::BI__builtin___stpncpy_chk:
1424 case Builtin::BI__builtin___memccpy_chk:
1425 case Builtin::BI__builtin___mempcpy_chk: {
1426 DiagID = diag::warn_builtin_chk_overflow;
1428 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1430 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1432 if (BuiltinID == Builtin::BI__builtin___memcpy_chk ||
1433 BuiltinID == Builtin::BI__builtin___memmove_chk ||
1434 BuiltinID == Builtin::BI__builtin___mempcpy_chk) {
1435 Checker.checkSourceOverread(1, 2);
1440 case Builtin::BI__builtin___snprintf_chk:
1441 case Builtin::BI__builtin___vsnprintf_chk: {
1442 DiagID = diag::warn_builtin_chk_overflow;
1443 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1444 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(3);
1448 case Builtin::BIstrncat:
1449 case Builtin::BI__builtin_strncat:
1450 case Builtin::BIstrncpy:
1451 case Builtin::BI__builtin_strncpy:
1452 case Builtin::BIstpncpy:
1453 case Builtin::BI__builtin_stpncpy: {
1459 DiagID = diag::warn_fortify_source_size_mismatch;
1461 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1462 DestinationSize = Checker.ComputeSizeArgument(0);
1466 case Builtin::BIbzero:
1467 case Builtin::BI__builtin_bzero:
1468 case Builtin::BImemcpy:
1469 case Builtin::BI__builtin_memcpy:
1470 case Builtin::BImemmove:
1471 case Builtin::BI__builtin_memmove:
1472 case Builtin::BImemset:
1473 case Builtin::BI__builtin_memset:
1474 case Builtin::BImempcpy:
1475 case Builtin::BI__builtin_mempcpy: {
1476 DiagID = diag::warn_fortify_source_overflow;
1478 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1479 DestinationSize = Checker.ComputeSizeArgument(0);
1482 if (BuiltinID != Builtin::BImemset &&
1483 BuiltinID != Builtin::BI__builtin_memset &&
1484 BuiltinID != Builtin::BIbzero &&
1485 BuiltinID != Builtin::BI__builtin_bzero) {
1486 Checker.checkSourceOverread(1, 2);
1490 case Builtin::BIbcopy:
1491 case Builtin::BI__builtin_bcopy: {
1492 DiagID = diag::warn_fortify_source_overflow;
1494 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1495 DestinationSize = Checker.ComputeSizeArgument(1);
1496 Checker.checkSourceOverread(0, 2);
1501 case Builtin::BImemchr:
1502 case Builtin::BI__builtin_memchr: {
1503 Checker.checkSourceOverread(0, 2);
1509 case Builtin::BImemcmp:
1510 case Builtin::BI__builtin_memcmp:
1511 case Builtin::BIbcmp:
1512 case Builtin::BI__builtin_bcmp: {
1513 Checker.checkSourceOverread(0, 2);
1514 Checker.checkSourceOverread(1, 2);
1517 case Builtin::BIsnprintf:
1518 case Builtin::BI__builtin_snprintf:
1519 case Builtin::BIvsnprintf:
1520 case Builtin::BI__builtin_vsnprintf: {
1521 DiagID = diag::warn_fortify_source_size_mismatch;
1522 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1524 StringRef FormatStrRef;
1528 EstimateSizeFormatHandler H(FormatStrRef);
1529 const char *FormatBytes = FormatStrRef.data();
1531 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1532 Context.getTargetInfo(),
false)) {
1533 llvm::APSInt FormatSize =
1534 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1535 .extOrTrunc(SizeTypeWidth);
1536 if (FormatSize > *SourceSize && *SourceSize != 0) {
1537 unsigned TruncationDiagID =
1538 H.isKernelCompatible() ? diag::warn_format_truncation
1539 : diag::warn_format_truncation_non_kprintf;
1540 SmallString<16> SpecifiedSizeStr;
1541 SmallString<16> FormatSizeStr;
1542 SourceSize->toString(SpecifiedSizeStr, 10);
1543 FormatSize.toString(FormatSizeStr, 10);
1545 PDiag(TruncationDiagID)
1546 << Checker.getFunctionName()
1547 << SpecifiedSizeStr << FormatSizeStr);
1551 DestinationSize = Checker.ComputeSizeArgument(0);
1555 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1559 if (!SourceSize || !DestinationSize ||
1560 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1563 std::string FunctionName = Checker.getFunctionName();
1565 SmallString<16> DestinationStr;
1566 SmallString<16> SourceStr;
1567 DestinationSize->toString(DestinationStr, 10);
1568 SourceSize->toString(SourceStr, 10);
1571 << FunctionName << DestinationStr << SourceStr);
1591 Expr *Arg = TheCall->
getArg(0);
1599 llvm::APInt RawValue =
R.Val.getInt();
1600 llvm::APInt Mask(RawValue.getBitWidth(), 0777);
1601 llvm::APInt
Extra = RawValue & ~Mask;
1604 SmallString<16> ExtraStr;
1605 Extra.toString(ExtraStr, 8,
false);
1622 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1625 << DRE->getDecl()->getIdentifier();
1637 "__builtin_alloca has invalid address space");
1663enum PointerAuthOpKind {
1679 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1710 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1713 llvm::raw_svector_ostream Str(
Value);
1722 Result = KeyValue->getZExtValue();
1741 bool IsAddrDiscArg =
false;
1746 IsAddrDiscArg =
true;
1755 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1756 <<
Result->getExtValue();
1758 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1764 IntVal =
Result->getZExtValue();
1768static std::pair<const ValueDecl *, CharUnits>
1775 const auto *BaseDecl =
1780 return {BaseDecl,
Result.Val.getLValueOffset()};
1784 bool RequireConstant =
false) {
1792 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1793 return OpKind != PAO_BlendInteger;
1795 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1796 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1797 OpKind == PAO_SignGeneric || OpKind == PAO_BlendPC;
1806 }
else if (AllowsInteger(OpKind) &&
1813 <<
unsigned(OpKind == PAO_Discriminator ? 1
1814 : OpKind == PAO_BlendPointer ? 2
1815 : OpKind == PAO_BlendInteger ? 3
1816 : OpKind == PAO_BlendPC ? 4
1818 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1828 if (!RequireConstant) {
1830 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1833 ? diag::warn_ptrauth_sign_null_pointer
1834 : diag::warn_ptrauth_auth_null_pointer)
1844 if (OpKind == PAO_Sign) {
1862 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1867 assert(OpKind == PAO_Discriminator);
1873 if (
Call->getBuiltinCallee() ==
1874 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1889 assert(
Pointer->getType()->isPointerType());
1901 assert(
Integer->getType()->isIntegerType());
1907 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1920 Call->setType(
Call->getArgs()[0]->getType());
1951 PointerAuthOpKind OpKind,
1952 bool RequireConstant) {
1963 Call->setType(
Call->getArgs()[0]->getType());
1979 Call->setType(
Call->getArgs()[0]->getType());
2000 unsigned OldKey = 0;
2003 if (OldKey !=
static_cast<unsigned>(AK::ASIA) &&
2004 OldKey !=
static_cast<unsigned>(AK::ASIB)) {
2005 S.
Diag(
Call->getArgs()[1]->getExprLoc(),
2006 diag::err_ptrauth_auth_with_pc_and_resign_invalid_key)
2007 << OldKey <<
Call->getArgs()[1]->getSourceRange();
2012 Call->setType(
Call->getArgs()[0]->getType());
2021 const Expr *AddendExpr =
Call->getArg(5);
2023 if (!AddendIsConstInt) {
2024 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
2038 Call->setType(
Call->getArgs()[0]->getType());
2047 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
2050 const auto *Literal = dyn_cast<StringLiteral>(Arg);
2051 if (!Literal || Literal->getCharByteWidth() != 1) {
2067 Call->setArg(0, FirstValue.
get());
2073 if (!FirstArgRecord) {
2074 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2075 << 0 << FirstArgType;
2080 diag::err_get_vtable_pointer_requires_complete_type)) {
2085 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2086 << 1 << FirstArgRecord;
2090 Call->setType(ReturnType);
2115 auto DiagSelect = [&]() -> std::optional<unsigned> {
2122 return std::optional<unsigned>{};
2137 diag::err_incomplete_type))
2141 "Unhandled non-object pointer case");
2169 if (PT->getPointeeType()->isFunctionType()) {
2171 diag::err_builtin_is_within_lifetime_invalid_arg)
2177 if (PT->getPointeeType()->isVariableArrayType()) {
2179 << 1 <<
"__builtin_is_within_lifetime";
2184 diag::err_builtin_is_within_lifetime_invalid_arg)
2198 diag::err_builtin_trivially_relocate_invalid_arg_type)
2205 diag::err_incomplete_type))
2209 T->isIncompleteArrayType()) {
2211 diag::err_builtin_trivially_relocate_invalid_arg_type)
2212 << (
T.isConstQualified() ? 1 : 2);
2221 diag::err_builtin_trivially_relocate_invalid_arg_type)
2228 if (Size.isInvalid())
2232 if (Size.isInvalid())
2234 SizeExpr = Size.get();
2235 TheCall->
setArg(2, SizeExpr);
2245 llvm::Triple::ObjectFormatType CurObjFormat =
2247 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2260 llvm::Triple::ArchType CurArch =
2262 if (llvm::is_contained(SupportedArchs, CurArch))
2272bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2279 case llvm::Triple::arm:
2280 case llvm::Triple::armeb:
2281 case llvm::Triple::thumb:
2282 case llvm::Triple::thumbeb:
2284 case llvm::Triple::aarch64:
2285 case llvm::Triple::aarch64_32:
2286 case llvm::Triple::aarch64_be:
2288 case llvm::Triple::bpfeb:
2289 case llvm::Triple::bpfel:
2291 case llvm::Triple::dxil:
2293 case llvm::Triple::hexagon:
2295 case llvm::Triple::mips:
2296 case llvm::Triple::mipsel:
2297 case llvm::Triple::mips64:
2298 case llvm::Triple::mips64el:
2300 case llvm::Triple::spirv:
2301 case llvm::Triple::spirv32:
2302 case llvm::Triple::spirv64:
2303 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2306 case llvm::Triple::systemz:
2308 case llvm::Triple::x86:
2309 case llvm::Triple::x86_64:
2311 case llvm::Triple::ppc:
2312 case llvm::Triple::ppcle:
2313 case llvm::Triple::ppc64:
2314 case llvm::Triple::ppc64le:
2316 case llvm::Triple::amdgpu:
2318 case llvm::Triple::riscv32:
2319 case llvm::Triple::riscv64:
2320 case llvm::Triple::riscv32be:
2321 case llvm::Triple::riscv64be:
2323 case llvm::Triple::loongarch32:
2324 case llvm::Triple::loongarch64:
2327 case llvm::Triple::wasm32:
2328 case llvm::Triple::wasm64:
2330 case llvm::Triple::nvptx:
2331 case llvm::Triple::nvptx64:
2337 return T->isDependentType() ||
2338 (
T->isRealType() && !
T->isBooleanType() && !
T->isEnumeralType());
2353 switch (ArgTyRestr) {
2357 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2358 << ArgOrdinal << 2 << 1 << 1
2365 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2366 << ArgOrdinal << 5 << 0
2372 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2373 << ArgOrdinal << 5 << 1
2379 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2393 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2394 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2395 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2396 "Expecting __builtin_cpu_...");
2398 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2400 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2401 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2402 (!IsCPUSupports && TInfo->supportsCpuIs()));
2404 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2411 ? diag::err_builtin_aix_os_unsupported
2412 : diag::err_builtin_target_unsupported)
2418 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2456 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2457 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2458 BT->getNumBits() != 1) {
2460 << ArgTy << BT->getNumBits();
2536 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2539 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2548 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2549 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2569 TheCall->
setArg(0, Arg0);
2586 TheCall->
setArg(1, Arg1);
2592 << 2 << 1 << 4 << 0 << Arg1Ty;
2606 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2608 << (OnlyUnsigned ? 3 : 1)
2616 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2619 return OnlyUnsigned ?
T->isUnsignedIntegerType() :
T->isIntegerType();
2624 return emitError(S, Loc,
T);
2629 return emitError(S, Loc,
T);
2635 return emitError(S, Loc,
T);
2640 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2645 return emitError(S, Loc,
T);
2650 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2656 llvm_unreachable(
"conversion functions are permitted");
2675 TheCall->
setArg(0, Arg0);
2689 TheCall->
setArg(1, Arg1);
2700 unsigned Pos,
bool AllowConst,
2704 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2709 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2710 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2711 << Pos <<
"scalar pointer";
2720 diag::err_typecheck_convert_incompatible)
2729 bool TypeDependent =
false;
2730 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2758 Builtin::BI__builtin_masked_load))
2772 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2795 Builtin::BI__builtin_masked_store))
2803 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2814 << MaskTy << ValTy);
2818 PtrTy->getPointeeType().getUnqualifiedType()))
2820 diag::err_vec_builtin_incompatible_vector)
2849 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2862 << MaskTy << IdxTy);
2871 diag::err_vec_masked_load_store_ptr)
2900 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2915 << MaskTy << IdxTy);
2921 << MaskTy << ValTy);
2924 PtrTy->getPointeeType().getUnqualifiedType()))
2926 diag::err_vec_builtin_incompatible_vector)
2940 if (Args.size() == 0) {
2942 diag::err_typecheck_call_too_few_args_at_least)
2948 QualType FuncT = Args[0]->getType();
2951 if (Args.size() < 2) {
2953 diag::err_typecheck_call_too_few_args_at_least)
2959 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2960 QualType ObjectT = Args[1]->getType();
2962 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
3011 tok::periodstar, ObjectArg.
get(), Args[0]);
3015 if (MPT->isMemberDataPointer())
3018 auto *MemCall =
new (S.
Context)
3042 return TyA->getElementType();
3049Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
3054 unsigned ICEArguments = 0;
3056 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
3061 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
3063 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
3068 if (ArgNo < TheCall->getNumArgs() &&
3071 ICEArguments &= ~(1 << ArgNo);
3075 switch (BuiltinID) {
3076 case Builtin::BI__builtin___get_unsafe_stack_start:
3077 case Builtin::BI__builtin___get_unsafe_stack_bottom:
3079 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3080 <<
"__safestack_get_unsafe_stack_bottom";
3082 case Builtin::BI__builtin___get_unsafe_stack_top:
3084 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3085 <<
"__safestack_get_unsafe_stack_top";
3087 case Builtin::BI__builtin___get_unsafe_stack_ptr:
3089 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3090 <<
"__safestack_get_unsafe_stack_ptr";
3092 case Builtin::BI__builtin_cpu_supports:
3093 case Builtin::BI__builtin_cpu_is:
3095 Context.getAuxTargetInfo(), BuiltinID))
3098 case Builtin::BI__builtin_cpu_init:
3099 if (!
Context.getTargetInfo().supportsCpuInit()) {
3105 case Builtin::BI__builtin___CFStringMakeConstantString:
3109 *
this, BuiltinID, TheCall,
3110 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
3113 "Wrong # arguments to builtin CFStringMakeConstantString");
3114 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
3117 case Builtin::BI__builtin_ms_va_start:
3118 case Builtin::BI__builtin_zos_va_start:
3119 case Builtin::BI__builtin_stdarg_start:
3120 case Builtin::BI__builtin_va_start:
3121 case Builtin::BI__builtin_c23_va_start:
3122 if (BuiltinVAStart(BuiltinID, TheCall))
3125 case Builtin::BI__va_start: {
3126 switch (
Context.getTargetInfo().getTriple().getArch()) {
3127 case llvm::Triple::aarch64:
3128 case llvm::Triple::arm:
3129 case llvm::Triple::thumb:
3130 if (BuiltinVAStartARMMicrosoft(TheCall))
3134 if (BuiltinVAStart(BuiltinID, TheCall))
3142 case Builtin::BI_interlockedbittestandset_acq:
3143 case Builtin::BI_interlockedbittestandset_rel:
3144 case Builtin::BI_interlockedbittestandset_nf:
3145 case Builtin::BI_interlockedbittestandreset_acq:
3146 case Builtin::BI_interlockedbittestandreset_rel:
3147 case Builtin::BI_interlockedbittestandreset_nf:
3150 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3155 case Builtin::BI_bittest64:
3156 case Builtin::BI_bittestandcomplement64:
3157 case Builtin::BI_bittestandreset64:
3158 case Builtin::BI_bittestandset64:
3159 case Builtin::BI_interlockedbittestandreset64:
3160 case Builtin::BI_interlockedbittestandset64:
3163 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3164 llvm::Triple::aarch64, llvm::Triple::amdgpu}))
3169 case Builtin::BI_interlockedbittestandreset64_acq:
3170 case Builtin::BI_interlockedbittestandreset64_rel:
3171 case Builtin::BI_interlockedbittestandreset64_nf:
3172 case Builtin::BI_interlockedbittestandset64_acq:
3173 case Builtin::BI_interlockedbittestandset64_rel:
3174 case Builtin::BI_interlockedbittestandset64_nf:
3179 case Builtin::BI__builtin_set_flt_rounds:
3182 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3183 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgpu,
3184 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3185 llvm::Triple::ppc64le}))
3189 case Builtin::BI__builtin_isgreater:
3190 case Builtin::BI__builtin_isgreaterequal:
3191 case Builtin::BI__builtin_isless:
3192 case Builtin::BI__builtin_islessequal:
3193 case Builtin::BI__builtin_islessgreater:
3194 case Builtin::BI__builtin_isunordered:
3195 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3198 case Builtin::BI__builtin_fpclassify:
3199 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3202 case Builtin::BI__builtin_isfpclass:
3203 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3206 case Builtin::BI__builtin_isfinite:
3207 case Builtin::BI__builtin_isinf:
3208 case Builtin::BI__builtin_isinf_sign:
3209 case Builtin::BI__builtin_isnan:
3210 case Builtin::BI__builtin_issignaling:
3211 case Builtin::BI__builtin_isnormal:
3212 case Builtin::BI__builtin_issubnormal:
3213 case Builtin::BI__builtin_iszero:
3214 case Builtin::BI__builtin_signbit:
3215 case Builtin::BI__builtin_signbitf:
3216 case Builtin::BI__builtin_signbitl:
3217 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3220 case Builtin::BI__builtin_shufflevector:
3224 case Builtin::BI__builtin_masked_load:
3225 case Builtin::BI__builtin_masked_expand_load:
3227 case Builtin::BI__builtin_masked_store:
3228 case Builtin::BI__builtin_masked_compress_store:
3230 case Builtin::BI__builtin_masked_gather:
3232 case Builtin::BI__builtin_masked_scatter:
3234 case Builtin::BI__builtin_invoke:
3236 case Builtin::BI__builtin_prefetch:
3237 if (BuiltinPrefetch(TheCall))
3240 case Builtin::BI__builtin_alloca_with_align:
3241 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3242 if (BuiltinAllocaWithAlign(TheCall))
3245 case Builtin::BI__builtin_alloca:
3246 case Builtin::BI__builtin_alloca_uninitialized:
3253 case Builtin::BI__builtin_infer_alloc_token:
3257 case Builtin::BI__arithmetic_fence:
3258 if (BuiltinArithmeticFence(TheCall))
3261 case Builtin::BI__assume:
3262 case Builtin::BI__builtin_assume:
3263 if (BuiltinAssume(TheCall))
3266 case Builtin::BI__builtin_assume_aligned:
3267 if (BuiltinAssumeAligned(TheCall))
3270 case Builtin::BI__builtin_dynamic_object_size:
3271 case Builtin::BI__builtin_object_size:
3275 case Builtin::BI__builtin_longjmp:
3276 if (BuiltinLongjmp(TheCall))
3279 case Builtin::BI__builtin_setjmp:
3280 if (BuiltinSetjmp(TheCall))
3283 case Builtin::BI__builtin_complex:
3284 if (BuiltinComplex(TheCall))
3287 case Builtin::BI__builtin_classify_type:
3288 case Builtin::BI__builtin_constant_p: {
3297 case Builtin::BI__builtin_launder:
3299 case Builtin::BI__builtin_is_within_lifetime:
3301 case Builtin::BI__builtin_trivially_relocate:
3303 case Builtin::BI__builtin_clear_padding: {
3307 const Expr *PtrArg = TheCall->
getArg(0);
3308 const QualType PtrArgType = PtrArg->
getType();
3311 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3322 diag::err_typecheck_decl_incomplete_type))
3328 auto IsAddrOfDeclExpr = [&]() {
3330 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3331 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3335 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3336 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3340 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3341 if (!VarDecl || VarDecl->getType()->isReferenceType())
3346 QualType VarQType = VarDecl->getType();
3348 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3353 && !IsAddrOfDeclExpr()) {
3354 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3361 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3368 case Builtin::BI__sync_fetch_and_add:
3369 case Builtin::BI__sync_fetch_and_add_1:
3370 case Builtin::BI__sync_fetch_and_add_2:
3371 case Builtin::BI__sync_fetch_and_add_4:
3372 case Builtin::BI__sync_fetch_and_add_8:
3373 case Builtin::BI__sync_fetch_and_add_16:
3374 case Builtin::BI__sync_fetch_and_sub:
3375 case Builtin::BI__sync_fetch_and_sub_1:
3376 case Builtin::BI__sync_fetch_and_sub_2:
3377 case Builtin::BI__sync_fetch_and_sub_4:
3378 case Builtin::BI__sync_fetch_and_sub_8:
3379 case Builtin::BI__sync_fetch_and_sub_16:
3380 case Builtin::BI__sync_fetch_and_or:
3381 case Builtin::BI__sync_fetch_and_or_1:
3382 case Builtin::BI__sync_fetch_and_or_2:
3383 case Builtin::BI__sync_fetch_and_or_4:
3384 case Builtin::BI__sync_fetch_and_or_8:
3385 case Builtin::BI__sync_fetch_and_or_16:
3386 case Builtin::BI__sync_fetch_and_and:
3387 case Builtin::BI__sync_fetch_and_and_1:
3388 case Builtin::BI__sync_fetch_and_and_2:
3389 case Builtin::BI__sync_fetch_and_and_4:
3390 case Builtin::BI__sync_fetch_and_and_8:
3391 case Builtin::BI__sync_fetch_and_and_16:
3392 case Builtin::BI__sync_fetch_and_xor:
3393 case Builtin::BI__sync_fetch_and_xor_1:
3394 case Builtin::BI__sync_fetch_and_xor_2:
3395 case Builtin::BI__sync_fetch_and_xor_4:
3396 case Builtin::BI__sync_fetch_and_xor_8:
3397 case Builtin::BI__sync_fetch_and_xor_16:
3398 case Builtin::BI__sync_fetch_and_nand:
3399 case Builtin::BI__sync_fetch_and_nand_1:
3400 case Builtin::BI__sync_fetch_and_nand_2:
3401 case Builtin::BI__sync_fetch_and_nand_4:
3402 case Builtin::BI__sync_fetch_and_nand_8:
3403 case Builtin::BI__sync_fetch_and_nand_16:
3404 case Builtin::BI__sync_add_and_fetch:
3405 case Builtin::BI__sync_add_and_fetch_1:
3406 case Builtin::BI__sync_add_and_fetch_2:
3407 case Builtin::BI__sync_add_and_fetch_4:
3408 case Builtin::BI__sync_add_and_fetch_8:
3409 case Builtin::BI__sync_add_and_fetch_16:
3410 case Builtin::BI__sync_sub_and_fetch:
3411 case Builtin::BI__sync_sub_and_fetch_1:
3412 case Builtin::BI__sync_sub_and_fetch_2:
3413 case Builtin::BI__sync_sub_and_fetch_4:
3414 case Builtin::BI__sync_sub_and_fetch_8:
3415 case Builtin::BI__sync_sub_and_fetch_16:
3416 case Builtin::BI__sync_and_and_fetch:
3417 case Builtin::BI__sync_and_and_fetch_1:
3418 case Builtin::BI__sync_and_and_fetch_2:
3419 case Builtin::BI__sync_and_and_fetch_4:
3420 case Builtin::BI__sync_and_and_fetch_8:
3421 case Builtin::BI__sync_and_and_fetch_16:
3422 case Builtin::BI__sync_or_and_fetch:
3423 case Builtin::BI__sync_or_and_fetch_1:
3424 case Builtin::BI__sync_or_and_fetch_2:
3425 case Builtin::BI__sync_or_and_fetch_4:
3426 case Builtin::BI__sync_or_and_fetch_8:
3427 case Builtin::BI__sync_or_and_fetch_16:
3428 case Builtin::BI__sync_xor_and_fetch:
3429 case Builtin::BI__sync_xor_and_fetch_1:
3430 case Builtin::BI__sync_xor_and_fetch_2:
3431 case Builtin::BI__sync_xor_and_fetch_4:
3432 case Builtin::BI__sync_xor_and_fetch_8:
3433 case Builtin::BI__sync_xor_and_fetch_16:
3434 case Builtin::BI__sync_nand_and_fetch:
3435 case Builtin::BI__sync_nand_and_fetch_1:
3436 case Builtin::BI__sync_nand_and_fetch_2:
3437 case Builtin::BI__sync_nand_and_fetch_4:
3438 case Builtin::BI__sync_nand_and_fetch_8:
3439 case Builtin::BI__sync_nand_and_fetch_16:
3440 case Builtin::BI__sync_val_compare_and_swap:
3441 case Builtin::BI__sync_val_compare_and_swap_1:
3442 case Builtin::BI__sync_val_compare_and_swap_2:
3443 case Builtin::BI__sync_val_compare_and_swap_4:
3444 case Builtin::BI__sync_val_compare_and_swap_8:
3445 case Builtin::BI__sync_val_compare_and_swap_16:
3446 case Builtin::BI__sync_bool_compare_and_swap:
3447 case Builtin::BI__sync_bool_compare_and_swap_1:
3448 case Builtin::BI__sync_bool_compare_and_swap_2:
3449 case Builtin::BI__sync_bool_compare_and_swap_4:
3450 case Builtin::BI__sync_bool_compare_and_swap_8:
3451 case Builtin::BI__sync_bool_compare_and_swap_16:
3452 case Builtin::BI__sync_lock_test_and_set:
3453 case Builtin::BI__sync_lock_test_and_set_1:
3454 case Builtin::BI__sync_lock_test_and_set_2:
3455 case Builtin::BI__sync_lock_test_and_set_4:
3456 case Builtin::BI__sync_lock_test_and_set_8:
3457 case Builtin::BI__sync_lock_test_and_set_16:
3458 case Builtin::BI__sync_lock_release:
3459 case Builtin::BI__sync_lock_release_1:
3460 case Builtin::BI__sync_lock_release_2:
3461 case Builtin::BI__sync_lock_release_4:
3462 case Builtin::BI__sync_lock_release_8:
3463 case Builtin::BI__sync_lock_release_16:
3464 case Builtin::BI__sync_swap:
3465 case Builtin::BI__sync_swap_1:
3466 case Builtin::BI__sync_swap_2:
3467 case Builtin::BI__sync_swap_4:
3468 case Builtin::BI__sync_swap_8:
3469 case Builtin::BI__sync_swap_16:
3470 return BuiltinAtomicOverloaded(TheCallResult);
3471 case Builtin::BI__sync_synchronize:
3475 case Builtin::BI__builtin_nontemporal_load:
3476 case Builtin::BI__builtin_nontemporal_store:
3477 return BuiltinNontemporalOverloaded(TheCallResult);
3478 case Builtin::BI__builtin_memcpy_inline: {
3479 clang::Expr *SizeOp = TheCall->
getArg(2);
3491 case Builtin::BI__builtin_memset_inline: {
3492 clang::Expr *SizeOp = TheCall->
getArg(2);
3502#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3503 case Builtin::BI##ID: \
3504 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3505#include "clang/Basic/Builtins.inc"
3506 case Builtin::BI__annotation: {
3507 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3508 if (!TT.isOSWindows() && !TT.isUEFI()) {
3517 case Builtin::BI__builtin_annotation:
3521 case Builtin::BI__builtin_addressof:
3525 case Builtin::BI__builtin_function_start:
3529 case Builtin::BI__builtin_is_aligned:
3530 case Builtin::BI__builtin_align_up:
3531 case Builtin::BI__builtin_align_down:
3535 case Builtin::BI__builtin_add_overflow:
3536 case Builtin::BI__builtin_sub_overflow:
3537 case Builtin::BI__builtin_mul_overflow:
3541 case Builtin::BI__builtin_operator_new:
3542 case Builtin::BI__builtin_operator_delete: {
3543 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3545 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3548 case Builtin::BI__builtin_dump_struct:
3550 case Builtin::BI__builtin_expect_with_probability: {
3555 const Expr *ProbArg = TheCall->
getArg(2);
3556 SmallVector<PartialDiagnosticAt, 8> Notes;
3557 Expr::EvalResult Eval;
3561 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3568 bool LoseInfo =
false;
3569 Probability.convert(llvm::APFloat::IEEEdouble(),
3570 llvm::RoundingMode::Dynamic, &LoseInfo);
3571 if (!(Probability >= llvm::APFloat(0.0) &&
3572 Probability <= llvm::APFloat(1.0))) {
3579 case Builtin::BI__builtin_preserve_access_index:
3583 case Builtin::BI__builtin_call_with_static_chain:
3587 case Builtin::BI__exception_code:
3588 case Builtin::BI_exception_code:
3590 diag::err_seh___except_block))
3593 case Builtin::BI__exception_info:
3594 case Builtin::BI_exception_info:
3596 diag::err_seh___except_filter))
3599 case Builtin::BI__GetExceptionInfo:
3611 case Builtin::BIaddressof:
3612 case Builtin::BI__addressof:
3613 case Builtin::BIforward:
3614 case Builtin::BIforward_like:
3615 case Builtin::BImove:
3616 case Builtin::BImove_if_noexcept:
3617 case Builtin::BIas_const: {
3625 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3626 BuiltinID == Builtin::BI__addressof;
3628 (ReturnsPointer ?
Result->isAnyPointerType()
3629 :
Result->isReferenceType()) &&
3632 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3638 case Builtin::BI__builtin_ptrauth_strip:
3640 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3642 case Builtin::BI__builtin_ptrauth_sign_constant:
3645 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3648 case Builtin::BI__builtin_ptrauth_auth:
3651 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3653 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3655 case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
3657 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3659 case Builtin::BI__builtin_ptrauth_string_discriminator:
3662 case Builtin::BI__builtin_get_vtable_pointer:
3666 case Builtin::BIread_pipe:
3667 case Builtin::BIwrite_pipe:
3670 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3673 case Builtin::BIreserve_read_pipe:
3674 case Builtin::BIreserve_write_pipe:
3675 case Builtin::BIwork_group_reserve_read_pipe:
3676 case Builtin::BIwork_group_reserve_write_pipe:
3677 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3680 case Builtin::BIsub_group_reserve_read_pipe:
3681 case Builtin::BIsub_group_reserve_write_pipe:
3682 if (
OpenCL().checkSubgroupExt(TheCall) ||
3683 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3686 case Builtin::BIcommit_read_pipe:
3687 case Builtin::BIcommit_write_pipe:
3688 case Builtin::BIwork_group_commit_read_pipe:
3689 case Builtin::BIwork_group_commit_write_pipe:
3690 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3693 case Builtin::BIsub_group_commit_read_pipe:
3694 case Builtin::BIsub_group_commit_write_pipe:
3695 if (
OpenCL().checkSubgroupExt(TheCall) ||
3696 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3699 case Builtin::BIget_pipe_num_packets:
3700 case Builtin::BIget_pipe_max_packets:
3701 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3704 case Builtin::BIto_global:
3705 case Builtin::BIto_local:
3706 case Builtin::BIto_private:
3707 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3711 case Builtin::BIenqueue_kernel:
3712 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3715 case Builtin::BIget_kernel_work_group_size:
3716 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3717 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3720 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3721 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3722 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3725 case Builtin::BI__builtin_os_log_format:
3726 Cleanup.setExprNeedsCleanups(
true);
3728 case Builtin::BI__builtin_os_log_format_buffer_size:
3729 if (BuiltinOSLogFormat(TheCall))
3732 case Builtin::BI__builtin_frame_address:
3733 case Builtin::BI__builtin_return_address: {
3742 Result.Val.getInt() != 0)
3744 << ((BuiltinID == Builtin::BI__builtin_return_address)
3745 ?
"__builtin_return_address"
3746 :
"__builtin_frame_address")
3751 case Builtin::BI__builtin_nondeterministic_value: {
3752 if (BuiltinNonDeterministicValue(TheCall))
3759 case Builtin::BI__builtin_elementwise_abs:
3767 case Builtin::BI__builtin_elementwise_acos:
3768 case Builtin::BI__builtin_elementwise_asin:
3769 case Builtin::BI__builtin_elementwise_atan:
3770 case Builtin::BI__builtin_elementwise_ceil:
3771 case Builtin::BI__builtin_elementwise_cos:
3772 case Builtin::BI__builtin_elementwise_cosh:
3773 case Builtin::BI__builtin_elementwise_exp:
3774 case Builtin::BI__builtin_elementwise_exp2:
3775 case Builtin::BI__builtin_elementwise_exp10:
3776 case Builtin::BI__builtin_elementwise_floor:
3777 case Builtin::BI__builtin_elementwise_log:
3778 case Builtin::BI__builtin_elementwise_log2:
3779 case Builtin::BI__builtin_elementwise_log10:
3780 case Builtin::BI__builtin_elementwise_roundeven:
3781 case Builtin::BI__builtin_elementwise_round:
3782 case Builtin::BI__builtin_elementwise_rint:
3783 case Builtin::BI__builtin_elementwise_nearbyint:
3784 case Builtin::BI__builtin_elementwise_sin:
3785 case Builtin::BI__builtin_elementwise_sinh:
3786 case Builtin::BI__builtin_elementwise_sqrt:
3787 case Builtin::BI__builtin_elementwise_tan:
3788 case Builtin::BI__builtin_elementwise_tanh:
3789 case Builtin::BI__builtin_elementwise_trunc:
3790 case Builtin::BI__builtin_elementwise_canonicalize:
3795 case Builtin::BI__builtin_elementwise_fma:
3800 case Builtin::BI__builtin_elementwise_ldexp: {
3822 const auto *Vec0 = TyA->
getAs<VectorType>();
3823 const auto *Vec1 = TyExp->
getAs<VectorType>();
3824 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3826 if (Arg0Length != Arg1Length) {
3828 diag::err_typecheck_vector_lengths_not_equal)
3842 case Builtin::BI__builtin_elementwise_minnum:
3843 case Builtin::BI__builtin_elementwise_maxnum:
3844 case Builtin::BI__builtin_elementwise_minimum:
3845 case Builtin::BI__builtin_elementwise_maximum:
3846 case Builtin::BI__builtin_elementwise_minimumnum:
3847 case Builtin::BI__builtin_elementwise_maximumnum:
3848 case Builtin::BI__builtin_elementwise_atan2:
3849 case Builtin::BI__builtin_elementwise_fmod:
3850 case Builtin::BI__builtin_elementwise_pow:
3851 if (BuiltinElementwiseMath(TheCall,
3857 case Builtin::BI__builtin_elementwise_add_sat:
3858 case Builtin::BI__builtin_elementwise_sub_sat:
3859 case Builtin::BI__builtin_elementwise_clmul:
3860 case Builtin::BI__builtin_elementwise_pext:
3861 case Builtin::BI__builtin_elementwise_pdep:
3862 if (BuiltinElementwiseMath(TheCall,
3866 case Builtin::BI__builtin_elementwise_fshl:
3867 case Builtin::BI__builtin_elementwise_fshr:
3872 case Builtin::BI__builtin_elementwise_min:
3873 case Builtin::BI__builtin_elementwise_max: {
3874 if (BuiltinElementwiseMath(TheCall))
3876 Expr *Arg0 = TheCall->
getArg(0);
3877 Expr *Arg1 = TheCall->
getArg(1);
3878 QualType Ty0 = Arg0->
getType();
3879 QualType Ty1 = Arg1->
getType();
3880 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3881 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3884 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3885 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3886 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3889 case Builtin::BI__builtin_elementwise_popcount:
3890 case Builtin::BI__builtin_elementwise_bitreverse:
3895 case Builtin::BI__builtin_elementwise_copysign: {
3904 QualType MagnitudeTy = Magnitude.
get()->
getType();
3917 diag::err_typecheck_call_different_arg_types)
3918 << MagnitudeTy << SignTy;
3926 case Builtin::BI__builtin_elementwise_clzg:
3927 case Builtin::BI__builtin_elementwise_ctzg:
3935 }
else if (BuiltinElementwiseMath(
3939 case Builtin::BI__builtin_reduce_max:
3940 case Builtin::BI__builtin_reduce_min: {
3941 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3944 const Expr *Arg = TheCall->
getArg(0);
3949 ElTy = TyA->getElementType();
3953 if (ElTy.isNull()) {
3963 case Builtin::BI__builtin_reduce_maximum:
3964 case Builtin::BI__builtin_reduce_minimum: {
3965 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3968 const Expr *Arg = TheCall->
getArg(0);
3973 ElTy = TyA->getElementType();
3977 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3990 case Builtin::BI__builtin_reduce_add:
3991 case Builtin::BI__builtin_reduce_mul:
3992 case Builtin::BI__builtin_reduce_xor:
3993 case Builtin::BI__builtin_reduce_or:
3994 case Builtin::BI__builtin_reduce_and: {
3995 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3998 const Expr *Arg = TheCall->
getArg(0);
4012 case Builtin::BI__builtin_reduce_assoc_fadd:
4013 case Builtin::BI__builtin_reduce_in_order_fadd: {
4015 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
4040 diag::err_builtin_invalid_arg_type)
4052 case Builtin::BI__builtin_matrix_transpose:
4053 return BuiltinMatrixTranspose(TheCall, TheCallResult);
4055 case Builtin::BI__builtin_matrix_column_major_load:
4056 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
4058 case Builtin::BI__builtin_matrix_column_major_store:
4059 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
4061 case Builtin::BI__builtin_verbose_trap:
4066 case Builtin::BI__builtin_get_device_side_mangled_name: {
4067 auto Check = [](CallExpr *TheCall) {
4073 auto *D = DRE->getDecl();
4076 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
4077 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
4079 if (!Check(TheCall)) {
4081 diag::err_hip_invalid_args_builtin_mangled_name);
4086 case Builtin::BI__builtin_bswapg:
4090 case Builtin::BI__builtin_bitreverseg:
4094 case Builtin::BI__builtin_popcountg:
4098 case Builtin::BI__builtin_clzg:
4099 case Builtin::BI__builtin_ctzg:
4104 case Builtin::BI__builtin_stdc_rotate_left:
4105 case Builtin::BI__builtin_stdc_rotate_right:
4110 case Builtin::BI__builtin_stdc_memreverse8:
4111 case Builtin::BIstdc_memreverse8:
4112 case Builtin::BIstdc_memreverse8u8:
4113 case Builtin::BIstdc_memreverse8u16:
4114 case Builtin::BIstdc_memreverse8u32:
4115 case Builtin::BIstdc_memreverse8u64:
4116 if (
Context.getTargetInfo().getCharWidth() != 8) {
4123 case Builtin::BI__builtin_stdc_bit_floor:
4124 case Builtin::BI__builtin_stdc_bit_ceil:
4128 case Builtin::BI__builtin_stdc_has_single_bit:
4132 case Builtin::BI__builtin_stdc_leading_zeros:
4133 case Builtin::BI__builtin_stdc_leading_ones:
4134 case Builtin::BI__builtin_stdc_trailing_zeros:
4135 case Builtin::BI__builtin_stdc_trailing_ones:
4136 case Builtin::BI__builtin_stdc_first_leading_zero:
4137 case Builtin::BI__builtin_stdc_first_leading_one:
4138 case Builtin::BI__builtin_stdc_first_trailing_zero:
4139 case Builtin::BI__builtin_stdc_first_trailing_one:
4140 case Builtin::BI__builtin_stdc_count_zeros:
4141 case Builtin::BI__builtin_stdc_count_ones:
4142 case Builtin::BI__builtin_stdc_bit_width:
4147 case Builtin::BI__builtin_allow_runtime_check: {
4148 Expr *Arg = TheCall->
getArg(0);
4158 case Builtin::BI__builtin_allow_sanitize_check: {
4162 Expr *Arg = TheCall->
getArg(0);
4164 const StringLiteral *SanitizerName =
4166 if (!SanitizerName) {
4172 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4173 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4174 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4178 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4184 case Builtin::BI__builtin_counted_by_ref:
4185 if (BuiltinCountedByRef(TheCall))
4195 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4196 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4197 assert(
Context.getAuxTargetInfo() &&
4198 "Aux Target Builtin, but not an aux target?");
4200 if (CheckTSBuiltinFunctionCall(
4202 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4205 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4211 return TheCallResult;
4226 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4230 diag::err_argument_not_contiguous_bit_field)
4237 bool IsVariadic =
false;
4240 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4241 IsVariadic = BD->isVariadic();
4242 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4243 IsVariadic = OMD->isVariadic();
4250 bool HasImplicitThisParam,
bool IsVariadic,
4254 else if (IsVariadic)
4264 if (HasImplicitThisParam) {
4296 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4297 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4298 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4299 Expr = ILE->getInit(0);
4309 const Expr *ArgExpr,
4313 S.
PDiag(diag::warn_null_arg)
4319 if (
auto nullability =
type->getNullability())
4330 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4336 llvm::SmallBitVector NonNullArgs;
4342 for (
const auto *Arg : Args)
4349 unsigned IdxAST = Idx.getASTIndex();
4350 if (IdxAST >= Args.size())
4352 if (NonNullArgs.empty())
4353 NonNullArgs.resize(Args.size());
4354 NonNullArgs.set(IdxAST);
4363 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4368 unsigned ParamIndex = 0;
4370 I != E; ++I, ++ParamIndex) {
4373 if (NonNullArgs.empty())
4374 NonNullArgs.resize(Args.size());
4376 NonNullArgs.set(ParamIndex);
4383 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4388 type = blockType->getPointeeType();
4402 if (NonNullArgs.empty())
4403 NonNullArgs.resize(Args.size());
4405 NonNullArgs.set(Index);
4414 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4415 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4416 if (NonNullArgs[ArgIndex])
4422 StringRef ParamName,
QualType ArgTy,
4445 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4446 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4450 if (ArgAlign < ParamAlign)
4451 Diag(Loc, diag::warn_param_mismatched_alignment)
4453 << ParamName << (FDecl !=
nullptr) << FDecl;
4457 const Expr *ThisArg,
4459 if (!FD || Args.empty())
4461 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4462 if (Idx == LifetimeCaptureByAttr::Global ||
4463 Idx == LifetimeCaptureByAttr::Unknown)
4465 if (IsMemberFunction && Idx == 0)
4467 return Args[Idx - IsMemberFunction];
4469 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4474 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4475 for (
int CapturingParamIdx :
Attr->params()) {
4476 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4480 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4483 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4490 for (
const auto *A :
4492 HandleCaptureByAttr(A, I + IsMemberFunction);
4494 if (IsMemberFunction) {
4502 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4512 llvm::any_of(Args, [](
const Expr *E) {
4513 return E && E->isInstantiationDependent();
4518 llvm::SmallBitVector CheckedVarArgs;
4520 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4522 CheckedVarArgs.resize(Args.size());
4523 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4528 CheckedVarArgs.resize(Args.size());
4529 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4536 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4540 : isa_and_nonnull<FunctionDecl>(FDecl)
4542 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4546 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4548 if (
const Expr *Arg = Args[ArgIdx]) {
4549 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4556 if (FDecl || Proto) {
4561 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4562 CheckArgumentWithTypeTag(I, Args, Loc);
4568 if (!Proto && FDecl) {
4570 if (isa_and_nonnull<FunctionProtoType>(FT))
4576 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4578 bool IsScalableArg =
false;
4579 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4581 if (
const Expr *Arg = Args[ArgIdx]) {
4585 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4593 IsScalableArg =
true;
4595 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4604 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4605 llvm::StringMap<bool> CallerFeatureMap;
4606 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4607 if (!CallerFeatureMap.contains(
"sme"))
4608 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4609 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4610 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4619 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4621 (IsScalableArg || IsScalableRet)) {
4622 bool IsCalleeStreaming =
4624 bool IsCalleeStreamingCompatible =
4628 if (!IsCalleeStreamingCompatible &&
4632 unsigned VL = LO.VScaleMin * 128;
4633 unsigned SVL = LO.VScaleStreamingMin * 128;
4634 bool IsVLMismatch = VL && SVL && VL != SVL;
4636 auto EmitDiag = [&](
bool IsArg) {
4640 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4641 << IsArg << IsCalleeStreaming << SVL << VL;
4644 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4645 << IsArg << SVL << VL;
4647 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4664 bool CallerHasZAState =
false;
4665 bool CallerHasZT0State =
false;
4667 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4669 CallerHasZAState =
true;
4671 CallerHasZT0State =
true;
4675 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4677 CallerHasZT0State |=
4679 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4685 Diag(Loc, diag::err_sme_za_call_no_za_state);
4688 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4692 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4693 Diag(Loc, diag::note_sme_use_preserves_za);
4698 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4699 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4700 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4701 if (!Arg->isValueDependent()) {
4703 if (Arg->EvaluateAsInt(Align,
Context)) {
4704 const llvm::APSInt &I = Align.
Val.
getInt();
4705 if (!I.isPowerOf2())
4706 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4707 << Arg->getSourceRange();
4710 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4719 << diag::OffloadLang::SYCL;
4741 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4742 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4744 checkCall(FDecl, Proto,
nullptr, Args,
true,
4753 IsMemberOperatorCall;
4759 Expr *ImplicitThis =
nullptr;
4764 ImplicitThis = Args[0];
4767 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4778 ThisType =
Context.getPointerType(ThisType);
4784 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4802 CheckAbsoluteValueFunction(TheCall, FDecl);
4803 CheckMaxUnsignedZero(TheCall, FDecl);
4804 CheckInfNaNFunction(TheCall, FDecl);
4815 case Builtin::BIstrlcpy:
4816 case Builtin::BIstrlcat:
4817 CheckStrlcpycatArguments(TheCall, FnInfo);
4819 case Builtin::BIstrncat:
4820 CheckStrncatArguments(TheCall, FnInfo);
4822 case Builtin::BIfree:
4823 CheckFreeArguments(TheCall);
4826 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4835 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4836 Ty =
V->getType().getNonReferenceType();
4837 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4838 Ty = F->getType().getNonReferenceType();
4875 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4878 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4880 case AtomicExpr::AO__c11_atomic_init:
4881 case AtomicExpr::AO__opencl_atomic_init:
4882 llvm_unreachable(
"There is no ordering argument for an init");
4884 case AtomicExpr::AO__c11_atomic_load:
4885 case AtomicExpr::AO__opencl_atomic_load:
4886 case AtomicExpr::AO__hip_atomic_load:
4887 case AtomicExpr::AO__atomic_load_n:
4888 case AtomicExpr::AO__atomic_load:
4889 case AtomicExpr::AO__scoped_atomic_load_n:
4890 case AtomicExpr::AO__scoped_atomic_load:
4891 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4892 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4894 case AtomicExpr::AO__c11_atomic_store:
4895 case AtomicExpr::AO__opencl_atomic_store:
4896 case AtomicExpr::AO__hip_atomic_store:
4897 case AtomicExpr::AO__atomic_store:
4898 case AtomicExpr::AO__atomic_store_n:
4899 case AtomicExpr::AO__scoped_atomic_store:
4900 case AtomicExpr::AO__scoped_atomic_store_n:
4901 case AtomicExpr::AO__atomic_clear:
4902 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4903 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4904 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4934#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4935 case AtomicExpr::AO__hip_atomic_##hip: \
4936 OldName = "__hip_atomic_" #hip; \
4937 NewName = "__scoped_atomic_" #scoped; \
4950#undef HIP_ATOMIC_FIXABLE
4951 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4952 OldName =
"__hip_atomic_compare_exchange_weak";
4953 NewName =
"__scoped_atomic_compare_exchange";
4956 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4957 OldName =
"__hip_atomic_compare_exchange_strong";
4958 NewName =
"__scoped_atomic_compare_exchange";
4962 llvm_unreachable(
"unhandled HIP atomic op");
4965 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4966 << OldName << NewName;
4973 std::optional<llvm::APSInt> ScopeVal =
4978 StringRef ScopeName;
4979 switch (ScopeVal->getZExtValue()) {
4981 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4984 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4987 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4990 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4993 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
4996 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
5048 const unsigned NumForm = ClearByte + 1;
5049 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
5050 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
5058 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
5059 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
5060 "need to update code for modified forms");
5061 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
5062 AtomicExpr::AO__atomic_xor_fetch + 1 ==
5063 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
5064 "need to update code for modified C11 atomics");
5065 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
5066 Op <= AtomicExpr::AO__opencl_atomic_store;
5067 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
5068 Op <= AtomicExpr::AO__hip_atomic_store;
5069 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
5070 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
5071 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
5072 Op <= AtomicExpr::AO__c11_atomic_store) ||
5074 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
5075 Op == AtomicExpr::AO__atomic_store_n ||
5076 Op == AtomicExpr::AO__atomic_exchange_n ||
5077 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
5078 Op == AtomicExpr::AO__scoped_atomic_load_n ||
5079 Op == AtomicExpr::AO__scoped_atomic_store_n ||
5080 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
5081 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
5085 enum ArithOpExtraValueType {
5091 unsigned ArithAllows = AOEVT_None;
5094 case AtomicExpr::AO__c11_atomic_init:
5095 case AtomicExpr::AO__opencl_atomic_init:
5099 case AtomicExpr::AO__c11_atomic_load:
5100 case AtomicExpr::AO__opencl_atomic_load:
5101 case AtomicExpr::AO__hip_atomic_load:
5102 case AtomicExpr::AO__atomic_load_n:
5103 case AtomicExpr::AO__scoped_atomic_load_n:
5104 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5108 case AtomicExpr::AO__atomic_load:
5109 case AtomicExpr::AO__scoped_atomic_load:
5110 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5114 case AtomicExpr::AO__c11_atomic_store:
5115 case AtomicExpr::AO__opencl_atomic_store:
5116 case AtomicExpr::AO__hip_atomic_store:
5117 case AtomicExpr::AO__atomic_store:
5118 case AtomicExpr::AO__atomic_store_n:
5119 case AtomicExpr::AO__scoped_atomic_store:
5120 case AtomicExpr::AO__scoped_atomic_store_n:
5121 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5124 case AtomicExpr::AO__atomic_fetch_add:
5125 case AtomicExpr::AO__atomic_fetch_sub:
5126 case AtomicExpr::AO__atomic_add_fetch:
5127 case AtomicExpr::AO__atomic_sub_fetch:
5128 case AtomicExpr::AO__scoped_atomic_fetch_add:
5129 case AtomicExpr::AO__scoped_atomic_fetch_sub:
5130 case AtomicExpr::AO__scoped_atomic_add_fetch:
5131 case AtomicExpr::AO__scoped_atomic_sub_fetch:
5132 case AtomicExpr::AO__c11_atomic_fetch_add:
5133 case AtomicExpr::AO__c11_atomic_fetch_sub:
5134 case AtomicExpr::AO__opencl_atomic_fetch_add:
5135 case AtomicExpr::AO__opencl_atomic_fetch_sub:
5136 case AtomicExpr::AO__hip_atomic_fetch_add:
5137 case AtomicExpr::AO__hip_atomic_fetch_sub:
5138 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5141 case AtomicExpr::AO__atomic_fetch_fminimum:
5142 case AtomicExpr::AO__atomic_fetch_fmaximum:
5143 case AtomicExpr::AO__atomic_fetch_fminimum_num:
5144 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
5145 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
5146 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
5147 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
5148 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
5149 ArithAllows = AOEVT_FP;
5152 case AtomicExpr::AO__atomic_fetch_max:
5153 case AtomicExpr::AO__atomic_fetch_min:
5154 case AtomicExpr::AO__atomic_max_fetch:
5155 case AtomicExpr::AO__atomic_min_fetch:
5156 case AtomicExpr::AO__scoped_atomic_fetch_max:
5157 case AtomicExpr::AO__scoped_atomic_fetch_min:
5158 case AtomicExpr::AO__scoped_atomic_max_fetch:
5159 case AtomicExpr::AO__scoped_atomic_min_fetch:
5160 case AtomicExpr::AO__c11_atomic_fetch_max:
5161 case AtomicExpr::AO__c11_atomic_fetch_min:
5162 case AtomicExpr::AO__opencl_atomic_fetch_max:
5163 case AtomicExpr::AO__opencl_atomic_fetch_min:
5164 case AtomicExpr::AO__hip_atomic_fetch_max:
5165 case AtomicExpr::AO__hip_atomic_fetch_min:
5166 ArithAllows = AOEVT_Int | AOEVT_FP;
5169 case AtomicExpr::AO__c11_atomic_fetch_and:
5170 case AtomicExpr::AO__c11_atomic_fetch_or:
5171 case AtomicExpr::AO__c11_atomic_fetch_xor:
5172 case AtomicExpr::AO__hip_atomic_fetch_and:
5173 case AtomicExpr::AO__hip_atomic_fetch_or:
5174 case AtomicExpr::AO__hip_atomic_fetch_xor:
5175 case AtomicExpr::AO__c11_atomic_fetch_nand:
5176 case AtomicExpr::AO__opencl_atomic_fetch_and:
5177 case AtomicExpr::AO__opencl_atomic_fetch_or:
5178 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5179 case AtomicExpr::AO__atomic_fetch_and:
5180 case AtomicExpr::AO__atomic_fetch_or:
5181 case AtomicExpr::AO__atomic_fetch_xor:
5182 case AtomicExpr::AO__atomic_fetch_nand:
5183 case AtomicExpr::AO__atomic_and_fetch:
5184 case AtomicExpr::AO__atomic_or_fetch:
5185 case AtomicExpr::AO__atomic_xor_fetch:
5186 case AtomicExpr::AO__atomic_nand_fetch:
5187 case AtomicExpr::AO__atomic_fetch_uinc:
5188 case AtomicExpr::AO__atomic_fetch_udec:
5189 case AtomicExpr::AO__scoped_atomic_fetch_and:
5190 case AtomicExpr::AO__scoped_atomic_fetch_or:
5191 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5192 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5193 case AtomicExpr::AO__scoped_atomic_and_fetch:
5194 case AtomicExpr::AO__scoped_atomic_or_fetch:
5195 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5196 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5197 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5198 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5202 case AtomicExpr::AO__c11_atomic_exchange:
5203 case AtomicExpr::AO__hip_atomic_exchange:
5204 case AtomicExpr::AO__opencl_atomic_exchange:
5205 case AtomicExpr::AO__atomic_exchange_n:
5206 case AtomicExpr::AO__scoped_atomic_exchange_n:
5207 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5211 case AtomicExpr::AO__atomic_exchange:
5212 case AtomicExpr::AO__scoped_atomic_exchange:
5213 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5217 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5218 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5219 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5220 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5221 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5222 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5226 case AtomicExpr::AO__atomic_compare_exchange:
5227 case AtomicExpr::AO__atomic_compare_exchange_n:
5228 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5229 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5230 ArithAllows = AOEVT_Pointer;
5234 case AtomicExpr::AO__atomic_test_and_set:
5235 Form = TestAndSetByte;
5238 case AtomicExpr::AO__atomic_clear:
5243 unsigned AdjustedNumArgs = NumArgs[Form];
5244 if ((IsOpenCL || IsHIP || IsScoped) &&
5245 Op != AtomicExpr::AO__opencl_atomic_init)
5248 if (Args.size() < AdjustedNumArgs) {
5249 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5250 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5253 }
else if (Args.size() > AdjustedNumArgs) {
5254 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5255 diag::err_typecheck_call_too_many_args)
5256 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5262 Expr *Ptr = Args[0];
5267 Ptr = ConvertedPtr.
get();
5270 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5280 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5286 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5292 }
else if (Form != Load && Form != LoadCopy) {
5294 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5300 if (Form != TestAndSetByte && Form != ClearByte) {
5303 diag::err_incomplete_type))
5306 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5307 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5317 pointerType->getPointeeType().getCVRQualifiers());
5327 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5337 auto IsAllowedValueType = [&](
QualType ValType,
5338 unsigned AllowedType) ->
bool {
5339 bool IsX87LongDouble =
5341 &
Context.getTargetInfo().getLongDoubleFormat() ==
5342 &llvm::APFloat::x87DoubleExtended();
5346 return (AllowedType & AOEVT_Int) || AllowedType != AOEVT_FP;
5348 return AllowedType & AOEVT_Pointer;
5352 if (IsX87LongDouble)
5356 if (!IsAllowedValueType(ValType, ArithAllows)) {
5358 ArithAllows == AOEVT_FP
5359 ? diag::err_atomic_op_needs_atomic_fp
5360 : (ArithAllows & AOEVT_FP
5361 ? (ArithAllows & AOEVT_Pointer
5362 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5363 : diag::err_atomic_op_needs_atomic_int_or_fp)
5364 : (ArithAllows & AOEVT_Pointer
5365 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5366 : diag::err_atomic_op_needs_atomic_int));
5373 diag::err_incomplete_type)) {
5384 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5400 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5412 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5415 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5421 bool IsPassedByAddress =
false;
5422 if (!IsC11 && !IsHIP && !IsN) {
5424 IsPassedByAddress =
true;
5429 APIOrderedArgs.push_back(Args[0]);
5433 APIOrderedArgs.push_back(Args[1]);
5439 APIOrderedArgs.push_back(Args[2]);
5440 APIOrderedArgs.push_back(Args[1]);
5443 APIOrderedArgs.push_back(Args[2]);
5444 APIOrderedArgs.push_back(Args[3]);
5445 APIOrderedArgs.push_back(Args[1]);
5448 APIOrderedArgs.push_back(Args[2]);
5449 APIOrderedArgs.push_back(Args[4]);
5450 APIOrderedArgs.push_back(Args[1]);
5451 APIOrderedArgs.push_back(Args[3]);
5454 APIOrderedArgs.push_back(Args[2]);
5455 APIOrderedArgs.push_back(Args[4]);
5456 APIOrderedArgs.push_back(Args[5]);
5457 APIOrderedArgs.push_back(Args[1]);
5458 APIOrderedArgs.push_back(Args[3]);
5460 case TestAndSetByte:
5462 APIOrderedArgs.push_back(Args[1]);
5466 APIOrderedArgs.append(Args.begin(), Args.end());
5473 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5475 if (i < NumVals[Form] + 1) {
5488 assert(Form != Load);
5490 Ty =
Context.getPointerDiffType();
5493 else if (Form ==
Copy || Form == Xchg) {
5494 if (IsPassedByAddress) {
5501 Expr *ValArg = APIOrderedArgs[i];
5508 AS = PtrTy->getPointeeType().getAddressSpace();
5517 if (IsPassedByAddress)
5537 APIOrderedArgs[i] = Arg.
get();
5542 SubExprs.push_back(Ptr);
5546 SubExprs.push_back(APIOrderedArgs[1]);
5549 case TestAndSetByte:
5551 SubExprs.push_back(APIOrderedArgs[1]);
5557 SubExprs.push_back(APIOrderedArgs[2]);
5558 SubExprs.push_back(APIOrderedArgs[1]);
5562 SubExprs.push_back(APIOrderedArgs[3]);
5563 SubExprs.push_back(APIOrderedArgs[1]);
5564 SubExprs.push_back(APIOrderedArgs[2]);
5567 SubExprs.push_back(APIOrderedArgs[3]);
5568 SubExprs.push_back(APIOrderedArgs[1]);
5569 SubExprs.push_back(APIOrderedArgs[4]);
5570 SubExprs.push_back(APIOrderedArgs[2]);
5573 SubExprs.push_back(APIOrderedArgs[4]);
5574 SubExprs.push_back(APIOrderedArgs[1]);
5575 SubExprs.push_back(APIOrderedArgs[5]);
5576 SubExprs.push_back(APIOrderedArgs[2]);
5577 SubExprs.push_back(APIOrderedArgs[3]);
5582 if (SubExprs.size() >= 2 && Form !=
Init) {
5583 std::optional<llvm::APSInt>
Success =
5584 SubExprs[1]->getIntegerConstantExpr(
Context);
5586 Diag(SubExprs[1]->getBeginLoc(),
5587 diag::warn_atomic_op_has_invalid_memory_order)
5588 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5589 << SubExprs[1]->getSourceRange();
5591 if (SubExprs.size() >= 5) {
5592 if (std::optional<llvm::APSInt>
Failure =
5593 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5594 if (!llvm::is_contained(
5595 {llvm::AtomicOrderingCABI::relaxed,
5596 llvm::AtomicOrderingCABI::consume,
5597 llvm::AtomicOrderingCABI::acquire,
5598 llvm::AtomicOrderingCABI::seq_cst},
5599 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5600 Diag(SubExprs[3]->getBeginLoc(),
5601 diag::warn_atomic_op_has_invalid_memory_order)
5602 << 2 << SubExprs[3]->getSourceRange();
5609 auto *
Scope = Args[Args.size() - 1];
5610 if (std::optional<llvm::APSInt>
Result =
5612 if (!ScopeModel->isValid(
Result->getZExtValue()))
5613 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5614 <<
Scope->getSourceRange();
5616 SubExprs.push_back(
Scope);
5625 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5626 Op == AtomicExpr::AO__c11_atomic_store ||
5627 Op == AtomicExpr::AO__opencl_atomic_load ||
5628 Op == AtomicExpr::AO__hip_atomic_load ||
5629 Op == AtomicExpr::AO__opencl_atomic_store ||
5630 Op == AtomicExpr::AO__hip_atomic_store) &&
5631 Context.AtomicUsesUnsupportedLibcall(AE))
5633 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5634 Op == AtomicExpr::AO__opencl_atomic_load ||
5635 Op == AtomicExpr::AO__hip_atomic_load)
5640 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5656 assert(Fn &&
"builtin call without direct callee!");
5672 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5679 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5681 <<
Callee->getSourceRange();
5690 Expr *FirstArg = TheCall->
getArg(0);
5694 FirstArg = FirstArgResult.
get();
5695 TheCall->
setArg(0, FirstArg);
5707 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5714 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5744 QualType ResultType = ValType;
5749#define BUILTIN_ROW(x) \
5750 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5751 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5753 static const unsigned BuiltinIndices[][5] = {
5778 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5779 case 1: SizeIndex = 0;
break;
5780 case 2: SizeIndex = 1;
break;
5781 case 4: SizeIndex = 2;
break;
5782 case 8: SizeIndex = 3;
break;
5783 case 16: SizeIndex = 4;
break;
5795 unsigned BuiltinIndex, NumFixed = 1;
5796 bool WarnAboutSemanticsChange =
false;
5797 switch (BuiltinID) {
5798 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5799 case Builtin::BI__sync_fetch_and_add:
5800 case Builtin::BI__sync_fetch_and_add_1:
5801 case Builtin::BI__sync_fetch_and_add_2:
5802 case Builtin::BI__sync_fetch_and_add_4:
5803 case Builtin::BI__sync_fetch_and_add_8:
5804 case Builtin::BI__sync_fetch_and_add_16:
5808 case Builtin::BI__sync_fetch_and_sub:
5809 case Builtin::BI__sync_fetch_and_sub_1:
5810 case Builtin::BI__sync_fetch_and_sub_2:
5811 case Builtin::BI__sync_fetch_and_sub_4:
5812 case Builtin::BI__sync_fetch_and_sub_8:
5813 case Builtin::BI__sync_fetch_and_sub_16:
5817 case Builtin::BI__sync_fetch_and_or:
5818 case Builtin::BI__sync_fetch_and_or_1:
5819 case Builtin::BI__sync_fetch_and_or_2:
5820 case Builtin::BI__sync_fetch_and_or_4:
5821 case Builtin::BI__sync_fetch_and_or_8:
5822 case Builtin::BI__sync_fetch_and_or_16:
5826 case Builtin::BI__sync_fetch_and_and:
5827 case Builtin::BI__sync_fetch_and_and_1:
5828 case Builtin::BI__sync_fetch_and_and_2:
5829 case Builtin::BI__sync_fetch_and_and_4:
5830 case Builtin::BI__sync_fetch_and_and_8:
5831 case Builtin::BI__sync_fetch_and_and_16:
5835 case Builtin::BI__sync_fetch_and_xor:
5836 case Builtin::BI__sync_fetch_and_xor_1:
5837 case Builtin::BI__sync_fetch_and_xor_2:
5838 case Builtin::BI__sync_fetch_and_xor_4:
5839 case Builtin::BI__sync_fetch_and_xor_8:
5840 case Builtin::BI__sync_fetch_and_xor_16:
5844 case Builtin::BI__sync_fetch_and_nand:
5845 case Builtin::BI__sync_fetch_and_nand_1:
5846 case Builtin::BI__sync_fetch_and_nand_2:
5847 case Builtin::BI__sync_fetch_and_nand_4:
5848 case Builtin::BI__sync_fetch_and_nand_8:
5849 case Builtin::BI__sync_fetch_and_nand_16:
5851 WarnAboutSemanticsChange =
true;
5854 case Builtin::BI__sync_add_and_fetch:
5855 case Builtin::BI__sync_add_and_fetch_1:
5856 case Builtin::BI__sync_add_and_fetch_2:
5857 case Builtin::BI__sync_add_and_fetch_4:
5858 case Builtin::BI__sync_add_and_fetch_8:
5859 case Builtin::BI__sync_add_and_fetch_16:
5863 case Builtin::BI__sync_sub_and_fetch:
5864 case Builtin::BI__sync_sub_and_fetch_1:
5865 case Builtin::BI__sync_sub_and_fetch_2:
5866 case Builtin::BI__sync_sub_and_fetch_4:
5867 case Builtin::BI__sync_sub_and_fetch_8:
5868 case Builtin::BI__sync_sub_and_fetch_16:
5872 case Builtin::BI__sync_and_and_fetch:
5873 case Builtin::BI__sync_and_and_fetch_1:
5874 case Builtin::BI__sync_and_and_fetch_2:
5875 case Builtin::BI__sync_and_and_fetch_4:
5876 case Builtin::BI__sync_and_and_fetch_8:
5877 case Builtin::BI__sync_and_and_fetch_16:
5881 case Builtin::BI__sync_or_and_fetch:
5882 case Builtin::BI__sync_or_and_fetch_1:
5883 case Builtin::BI__sync_or_and_fetch_2:
5884 case Builtin::BI__sync_or_and_fetch_4:
5885 case Builtin::BI__sync_or_and_fetch_8:
5886 case Builtin::BI__sync_or_and_fetch_16:
5890 case Builtin::BI__sync_xor_and_fetch:
5891 case Builtin::BI__sync_xor_and_fetch_1:
5892 case Builtin::BI__sync_xor_and_fetch_2:
5893 case Builtin::BI__sync_xor_and_fetch_4:
5894 case Builtin::BI__sync_xor_and_fetch_8:
5895 case Builtin::BI__sync_xor_and_fetch_16:
5899 case Builtin::BI__sync_nand_and_fetch:
5900 case Builtin::BI__sync_nand_and_fetch_1:
5901 case Builtin::BI__sync_nand_and_fetch_2:
5902 case Builtin::BI__sync_nand_and_fetch_4:
5903 case Builtin::BI__sync_nand_and_fetch_8:
5904 case Builtin::BI__sync_nand_and_fetch_16:
5906 WarnAboutSemanticsChange =
true;
5909 case Builtin::BI__sync_val_compare_and_swap:
5910 case Builtin::BI__sync_val_compare_and_swap_1:
5911 case Builtin::BI__sync_val_compare_and_swap_2:
5912 case Builtin::BI__sync_val_compare_and_swap_4:
5913 case Builtin::BI__sync_val_compare_and_swap_8:
5914 case Builtin::BI__sync_val_compare_and_swap_16:
5919 case Builtin::BI__sync_bool_compare_and_swap:
5920 case Builtin::BI__sync_bool_compare_and_swap_1:
5921 case Builtin::BI__sync_bool_compare_and_swap_2:
5922 case Builtin::BI__sync_bool_compare_and_swap_4:
5923 case Builtin::BI__sync_bool_compare_and_swap_8:
5924 case Builtin::BI__sync_bool_compare_and_swap_16:
5930 case Builtin::BI__sync_lock_test_and_set:
5931 case Builtin::BI__sync_lock_test_and_set_1:
5932 case Builtin::BI__sync_lock_test_and_set_2:
5933 case Builtin::BI__sync_lock_test_and_set_4:
5934 case Builtin::BI__sync_lock_test_and_set_8:
5935 case Builtin::BI__sync_lock_test_and_set_16:
5939 case Builtin::BI__sync_lock_release:
5940 case Builtin::BI__sync_lock_release_1:
5941 case Builtin::BI__sync_lock_release_2:
5942 case Builtin::BI__sync_lock_release_4:
5943 case Builtin::BI__sync_lock_release_8:
5944 case Builtin::BI__sync_lock_release_16:
5950 case Builtin::BI__sync_swap:
5951 case Builtin::BI__sync_swap_1:
5952 case Builtin::BI__sync_swap_2:
5953 case Builtin::BI__sync_swap_4:
5954 case Builtin::BI__sync_swap_8:
5955 case Builtin::BI__sync_swap_16:
5963 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5964 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5965 <<
Callee->getSourceRange();
5969 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5970 <<
Callee->getSourceRange();
5972 if (WarnAboutSemanticsChange) {
5973 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5974 <<
Callee->getSourceRange();
5979 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5980 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5981 FunctionDecl *NewBuiltinDecl;
5982 if (NewBuiltinID == BuiltinID)
5983 NewBuiltinDecl = FDecl;
5986 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5989 assert(Res.getFoundDecl());
5990 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5991 if (!NewBuiltinDecl)
5998 for (
unsigned i = 0; i != NumFixed; ++i) {
6027 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
6029 CK_BuiltinFnToFnPtr);
6040 const auto *BitIntValType = ValType->
getAs<BitIntType>();
6041 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
6042 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
6046 return TheCallResult;
6050 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
6055 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
6056 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
6057 "Unexpected nontemporal load/store builtin!");
6058 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
6059 unsigned numArgs = isStore ? 2 : 1;
6069 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
6075 PointerArg = PointerArgResult.
get();
6076 TheCall->
setArg(numArgs - 1, PointerArg);
6080 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
6093 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
6100 return TheCallResult;
6112 return TheCallResult;
6119 auto *
Literal = dyn_cast<StringLiteral>(Arg);
6121 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
6122 Literal = ObjcLiteral->getString();
6126 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
6133 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
6134 InitializedEntity Entity =
6144 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
6145 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
6146 TT.getArch() == llvm::Triple::aarch64_32);
6147 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
6148 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
6149 if (IsX64 || IsAArch64) {
6156 return S.
Diag(Fn->getBeginLoc(),
6157 diag::err_ms_va_start_used_in_sysv_function);
6164 (!IsWindowsOrUEFI && CC ==
CC_Win64))
6165 return S.
Diag(Fn->getBeginLoc(),
6166 diag::err_va_start_used_in_wrong_abi_function)
6167 << !IsWindowsOrUEFI;
6173 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6181 bool IsVariadic =
false;
6184 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6185 IsVariadic =
Block->isVariadic();
6186 Params =
Block->parameters();
6187 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6190 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6191 IsVariadic = MD->isVariadic();
6193 Params = MD->parameters();
6196 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6200 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6205 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6210 *LastParam = Params.empty() ?
nullptr : Params.back();
6215bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6220 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6244 ParmVarDecl *LastParam;
6255 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6257 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6262 if (std::optional<llvm::APSInt> Val =
6264 Val &&
LangOpts.C23 && *Val == 0 &&
6265 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6266 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6273 SourceLocation ParamLoc;
6274 bool IsCRegister =
false;
6275 bool SecondArgIsLastNonVariadicArgument =
false;
6276 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6277 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6278 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6281 ParamLoc = PV->getLocation();
6287 if (!SecondArgIsLastNonVariadicArgument)
6289 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6290 else if (IsCRegister ||
Type->isReferenceType() ||
6291 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6294 if (!Context.isPromotableIntegerType(Type))
6296 const auto *ED = Type->getAsEnumDecl();
6299 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6301 unsigned Reason = 0;
6302 if (
Type->isReferenceType()) Reason = 1;
6303 else if (IsCRegister) Reason = 2;
6304 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6305 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6312 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6332 if (
Call->getNumArgs() < 3)
6334 diag::err_typecheck_call_too_few_args_at_least)
6335 << 0 << 3 <<
Call->getNumArgs()
6351 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6354 const QualType &ConstCharPtrTy =
6356 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6358 << Arg1->
getType() << ConstCharPtrTy << 1
6361 << 2 << Arg1->
getType() << ConstCharPtrTy;
6363 const QualType SizeTy =
Context.getSizeType();
6368 << Arg2->
getType() << SizeTy << 1
6371 << 3 << Arg2->
getType() << SizeTy;
6376bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6380 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6408 diag::err_typecheck_call_invalid_ordered_compare)
6416bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6417 unsigned BuiltinID) {
6422 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6423 BuiltinID == Builtin::BI__builtin_isinf ||
6424 BuiltinID == Builtin::BI__builtin_isinf_sign))
6428 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6429 BuiltinID == Builtin::BI__builtin_isunordered))
6433 bool IsFPClass = NumArgs == 2;
6436 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6440 for (
unsigned i = 0; i < FPArgNo; ++i) {
6441 Expr *Arg = TheCall->
getArg(i);
6454 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6463 OrigArg = Res.
get();
6465 TheCall->
setArg(FPArgNo, OrigArg);
6467 QualType VectorResultTy;
6468 QualType ElementTy = OrigArg->
getType();
6473 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6479 diag::err_typecheck_call_invalid_unary_fp)
6491 if (!VectorResultTy.
isNull())
6492 ResultTy = VectorResultTy;
6501bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6506 for (
unsigned I = 0; I != 2; ++I) {
6507 Expr *Arg = TheCall->
getArg(I);
6517 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6532 Expr *Real = TheCall->
getArg(0);
6533 Expr *Imag = TheCall->
getArg(1);
6536 diag::err_typecheck_call_different_arg_types)
6551 diag::err_typecheck_call_too_few_args_at_least)
6552 << 0 << 2 << NumArgs
6559 unsigned NumElements = 0;
6574 unsigned NumResElements = NumArgs - 2;
6583 diag::err_vec_builtin_incompatible_vector)
6588 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6590 diag::err_vec_builtin_incompatible_vector)
6595 }
else if (NumElements != NumResElements) {
6598 ?
Context.getExtVectorType(EltType, NumResElements)
6599 :
Context.getVectorType(EltType, NumResElements,
6604 for (
unsigned I = 2; I != NumArgs; ++I) {
6612 diag::err_shufflevector_nonconstant_argument)
6618 else if (
Result->getActiveBits() > 64 ||
6619 Result->getZExtValue() >= NumElements * 2)
6621 diag::err_shufflevector_argument_too_large)
6646 diag::err_convertvector_non_vector)
6649 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6651 <<
"__builtin_convertvector");
6656 if (SrcElts != DstElts)
6658 diag::err_convertvector_incompatible_vector)
6666bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6671 diag::err_typecheck_call_too_many_args_at_most)
6672 << 0 << 3 << NumArgs << 0
6677 for (
unsigned i = 1; i != NumArgs; ++i)
6684bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6685 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6686 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6696 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6706bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6707 Expr *Arg = TheCall->
getArg(0);
6718bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6720 Expr *Arg = TheCall->
getArg(1);
6724 if (
const auto *UE =
6726 if (UE->getKind() == UETT_AlignOf ||
6727 UE->getKind() == UETT_PreferredAlignOf)
6733 if (!
Result.isPowerOf2())
6734 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6741 if (
Result > std::numeric_limits<int32_t>::max())
6749bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6754 Expr *FirstArg = TheCall->
getArg(0);
6760 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6764 TheCall->
setArg(0, FirstArgResult.
get());
6768 Expr *SecondArg = TheCall->
getArg(1);
6776 if (!
Result.isPowerOf2())
6777 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6789 Expr *ThirdArg = TheCall->
getArg(2);
6792 TheCall->
setArg(2, ThirdArg);
6798bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6799 unsigned BuiltinID =
6801 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6804 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6805 if (NumArgs < NumRequiredArgs) {
6806 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6807 << 0 << NumRequiredArgs << NumArgs
6810 if (NumArgs >= NumRequiredArgs + 0x100) {
6812 diag::err_typecheck_call_too_many_args_at_most)
6813 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6824 if (Arg.isInvalid())
6826 TheCall->
setArg(i, Arg.get());
6831 unsigned FormatIdx = i;
6841 unsigned FirstDataArg = i;
6842 while (i < NumArgs) {
6860 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6862 bool Success = CheckFormatArguments(
6865 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6889 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6898 int High,
bool RangeIsError) {
6912 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6920 PDiag(diag::warn_argument_invalid_range)
6963 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6968 if (
Value.isNegative())
6979 if ((
Value & 0xFF) != 0)
7004 Result.setIsUnsigned(
true);
7009 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
7029 Result.setIsUnsigned(
true);
7037 diag::err_argument_not_shifted_byte_or_xxff)
7041bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
7042 if (!Context.getTargetInfo().hasSjLjLowering())
7043 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
7054 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
7060bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
7061 if (!Context.getTargetInfo().hasSjLjLowering())
7062 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
7067bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
7082 diag::err_builtin_counted_by_ref_invalid_arg)
7087 diag::err_builtin_counted_by_ref_has_side_effects)
7090 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
7092 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
7097 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
7104 QualType MemberTy = ME->getMemberDecl()->getType();
7107 diag::err_builtin_counted_by_ref_invalid_arg)
7111 diag::err_builtin_counted_by_ref_invalid_arg)
7121bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
7123 const CallExpr *CE =
7132 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7137 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7142 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7146 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7150 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7160class UncoveredArgHandler {
7161 enum {
Unknown = -1, AllCovered = -2 };
7163 signed FirstUncoveredArg =
Unknown;
7164 SmallVector<const Expr *, 4> DiagnosticExprs;
7167 UncoveredArgHandler() =
default;
7169 bool hasUncoveredArg()
const {
7170 return (FirstUncoveredArg >= 0);
7173 unsigned getUncoveredArg()
const {
7174 assert(hasUncoveredArg() &&
"no uncovered argument");
7175 return FirstUncoveredArg;
7178 void setAllCovered() {
7181 DiagnosticExprs.clear();
7182 FirstUncoveredArg = AllCovered;
7185 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7186 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7189 if (FirstUncoveredArg == AllCovered)
7194 if (NewFirstUncoveredArg == FirstUncoveredArg)
7195 DiagnosticExprs.push_back(StrExpr);
7196 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7197 DiagnosticExprs.clear();
7198 DiagnosticExprs.push_back(StrExpr);
7199 FirstUncoveredArg = NewFirstUncoveredArg;
7203 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7206enum StringLiteralCheckType {
7208 SLCT_UncheckedLiteral,
7216 bool AddendIsRight) {
7217 unsigned BitWidth = Offset.getBitWidth();
7218 unsigned AddendBitWidth = Addend.getBitWidth();
7220 if (Addend.isUnsigned()) {
7221 Addend = Addend.zext(++AddendBitWidth);
7222 Addend.setIsSigned(
true);
7225 if (AddendBitWidth > BitWidth) {
7226 Offset = Offset.sext(AddendBitWidth);
7227 BitWidth = AddendBitWidth;
7228 }
else if (BitWidth > AddendBitWidth) {
7229 Addend = Addend.sext(BitWidth);
7233 llvm::APSInt ResOffset = Offset;
7234 if (BinOpKind == BO_Add)
7235 ResOffset = Offset.sadd_ov(Addend, Ov);
7237 assert(AddendIsRight && BinOpKind == BO_Sub &&
7238 "operator must be add or sub with addend on the right");
7239 ResOffset = Offset.ssub_ov(Addend, Ov);
7245 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7246 "index (intermediate) result too big");
7247 Offset = Offset.sext(2 * BitWidth);
7248 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7252 Offset = std::move(ResOffset);
7260class FormatStringLiteral {
7261 const StringLiteral *FExpr;
7265 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7266 : FExpr(fexpr), Offset(Offset) {}
7268 const StringLiteral *getFormatString()
const {
return FExpr; }
7270 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7272 unsigned getByteLength()
const {
7273 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7276 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7283 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7284 bool isWide()
const {
return FExpr->
isWide(); }
7285 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7286 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7287 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7288 bool isPascal()
const {
return FExpr->
isPascal(); }
7290 SourceLocation getLocationOfByte(
7291 unsigned ByteNo,
const SourceManager &SM,
const LangOptions &Features,
7292 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7293 unsigned *StartTokenByteOffset =
nullptr)
const {
7295 StartToken, StartTokenByteOffset);
7298 SourceLocation getBeginLoc() const LLVM_READONLY {
7302 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7308 Sema &S,
const FormatStringLiteral *FExpr,
7313 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7314 bool IgnoreStringsWithoutSpecifiers);
7323static StringLiteralCheckType
7329 llvm::SmallBitVector &CheckedVarArgs,
7330 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7331 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7332 bool IgnoreStringsWithoutSpecifiers =
false) {
7334 return SLCT_NotALiteral;
7336 assert(Offset.isSigned() &&
"invalid offset");
7339 return SLCT_NotALiteral;
7348 return SLCT_UncheckedLiteral;
7351 case Stmt::InitListExprClass:
7355 format_idx, firstDataArg,
Type, CallType,
7356 false, CheckedVarArgs,
7357 UncoveredArg, Offset, CallerFormatParamIdx,
7358 IgnoreStringsWithoutSpecifiers);
7360 return SLCT_NotALiteral;
7361 case Stmt::BinaryConditionalOperatorClass:
7362 case Stmt::ConditionalOperatorClass: {
7371 bool CheckLeft =
true, CheckRight =
true;
7374 if (
C->getCond()->EvaluateAsBooleanCondition(
7386 StringLiteralCheckType Left;
7388 Left = SLCT_UncheckedLiteral;
7391 Args, APK, format_idx, firstDataArg,
Type,
7392 CallType, InFunctionCall, CheckedVarArgs,
7393 UncoveredArg, Offset, CallerFormatParamIdx,
7394 IgnoreStringsWithoutSpecifiers);
7395 if (Left == SLCT_NotALiteral || !CheckRight) {
7401 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7402 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7403 UncoveredArg, Offset, CallerFormatParamIdx,
7404 IgnoreStringsWithoutSpecifiers);
7406 return (CheckLeft && Left < Right) ? Left : Right;
7409 case Stmt::ImplicitCastExprClass:
7413 case Stmt::OpaqueValueExprClass:
7418 return SLCT_NotALiteral;
7420 case Stmt::PredefinedExprClass:
7424 return SLCT_UncheckedLiteral;
7426 case Stmt::DeclRefExprClass: {
7432 bool isConstant =
false;
7436 isConstant = AT->getElementType().isConstant(S.
Context);
7438 isConstant =
T.isConstant(S.
Context) &&
7439 PT->getPointeeType().isConstant(S.
Context);
7440 }
else if (
T->isObjCObjectPointerType()) {
7443 isConstant =
T.isConstant(S.
Context);
7447 if (
const Expr *
Init = VD->getAnyInitializer()) {
7450 if (InitList->isStringLiteralInit())
7451 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7454 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7455 firstDataArg,
Type, CallType,
false,
7456 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7507 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7508 if (CallerFormatParamIdx)
7509 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7510 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7511 for (
const auto *PVFormatMatches :
7512 D->specific_attrs<FormatMatchesAttr>()) {
7517 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7521 S.
Diag(Args[format_idx]->getBeginLoc(),
7522 diag::warn_format_string_type_incompatible)
7523 << PVFormatMatches->getType()->getName()
7525 if (!InFunctionCall) {
7526 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7527 diag::note_format_string_defined);
7529 return SLCT_UncheckedLiteral;
7532 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7533 Args, APK, format_idx, firstDataArg,
Type, CallType,
7534 false, CheckedVarArgs, UncoveredArg,
7535 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7539 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7542 PVFormat->getFirstArg(), &CallerFSI))
7544 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7548 S.
Diag(Args[format_idx]->getBeginLoc(),
7549 diag::warn_format_string_type_incompatible)
7550 << PVFormat->getType()->getName()
7552 if (!InFunctionCall) {
7555 return SLCT_UncheckedLiteral;
7568 return SLCT_UncheckedLiteral;
7576 return SLCT_NotALiteral;
7579 case Stmt::CallExprClass:
7580 case Stmt::CXXMemberCallExprClass: {
7584 StringLiteralCheckType CommonResult;
7585 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7586 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7588 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7589 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7590 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7597 return CommonResult;
7599 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7601 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7602 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7605 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7606 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7607 UncoveredArg, Offset, CallerFormatParamIdx,
7608 IgnoreStringsWithoutSpecifiers);
7614 format_idx, firstDataArg,
Type, CallType,
7615 false, CheckedVarArgs,
7616 UncoveredArg, Offset, CallerFormatParamIdx,
7617 IgnoreStringsWithoutSpecifiers);
7618 return SLCT_NotALiteral;
7620 case Stmt::ObjCMessageExprClass: {
7622 if (
const auto *MD = ME->getMethodDecl()) {
7623 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7632 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7634 MD->getSelector().isKeywordSelector(
7635 {
"localizedStringForKey",
"value",
"table"})) {
7636 IgnoreStringsWithoutSpecifiers =
true;
7639 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7641 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7642 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7643 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7647 return SLCT_NotALiteral;
7649 case Stmt::ObjCStringLiteralClass:
7650 case Stmt::StringLiteralClass: {
7659 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7662 return SLCT_NotALiteral;
7664 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7666 format_idx, firstDataArg,
Type, InFunctionCall,
7667 CallType, CheckedVarArgs, UncoveredArg,
7668 IgnoreStringsWithoutSpecifiers);
7669 return SLCT_CheckedLiteral;
7672 return SLCT_NotALiteral;
7674 case Stmt::BinaryOperatorClass: {
7688 if (LIsInt != RIsInt) {
7692 if (BinOpKind == BO_Add) {
7705 return SLCT_NotALiteral;
7707 case Stmt::UnaryOperatorClass: {
7709 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7710 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7712 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7722 return SLCT_NotALiteral;
7726 return SLCT_NotALiteral;
7737 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7738 if (isa_and_nonnull<StringLiteral>(LVE))
7759 return "freebsd_kprintf";
7768 return llvm::StringSwitch<FormatStringType>(Flavor)
7770 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7775 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7791bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7795 llvm::SmallBitVector &CheckedVarArgs) {
7796 FormatStringInfo FSI;
7800 return CheckFormatArguments(
7801 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7806bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7810 llvm::SmallBitVector &CheckedVarArgs) {
7811 FormatStringInfo FSI;
7815 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7816 Format->getFormatString(), FSI.FormatIdx,
7818 CallType, Loc, Range, CheckedVarArgs);
7826 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7839 unsigned CallerArgumentIndexOffset =
7842 unsigned FirstArgumentIndex = -1;
7852 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7853 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7857 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7858 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7860 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7863 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7864 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7867 FirstArgumentIndex =
7868 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7874 ? (NumCallerParams + CallerArgumentIndexOffset)
7879 if (!ReferenceFormatString)
7885 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7887 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7889 std::string
Attr, Fixit;
7890 llvm::raw_string_ostream AttrOS(
Attr);
7892 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7893 << FirstArgumentIndex <<
")";
7895 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7897 AttrOS.write_escaped(ReferenceFormatString->
getString());
7901 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7912 llvm::raw_string_ostream IS(Fixit);
7920 if (LO.C23 || LO.CPlusPlus11)
7921 IS <<
"[[gnu::" <<
Attr <<
"]]";
7922 else if (LO.ObjC || LO.GNUMode)
7923 IS <<
"__attribute__((" <<
Attr <<
"))";
7937 Caller->
addAttr(FormatAttr::CreateImplicit(
7939 FormatStringIndex, FirstArgumentIndex));
7941 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7943 FormatStringIndex, ReferenceFormatString));
7947 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7959 unsigned format_idx,
unsigned firstDataArg,
7963 llvm::SmallBitVector &CheckedVarArgs) {
7965 if (format_idx >= Args.size()) {
7966 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7970 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7984 UncoveredArgHandler UncoveredArg;
7985 std::optional<unsigned> CallerParamIdx;
7987 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7988 firstDataArg,
Type, CallType,
7989 true, CheckedVarArgs, UncoveredArg,
7990 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7993 if (UncoveredArg.hasUncoveredArg()) {
7994 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7995 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7996 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7999 if (CT != SLCT_NotALiteral)
8001 return CT == SLCT_CheckedLiteral;
8007 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
8013 this, Args, APK, ReferenceFormatString, format_idx,
8014 firstDataArg,
Type, *CallerParamIdx, Loc))
8024 if (Args.size() == firstDataArg) {
8025 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
8033 Diag(FormatLoc, diag::note_format_security_fixit)
8037 Diag(FormatLoc, diag::note_format_security_fixit)
8042 Diag(FormatLoc, diag::warn_format_nonliteral)
8053 const FormatStringLiteral *FExpr;
8054 const Expr *OrigFormatExpr;
8056 const unsigned FirstDataArg;
8057 const unsigned NumDataArgs;
8060 ArrayRef<const Expr *> Args;
8062 llvm::SmallBitVector CoveredArgs;
8063 bool usesPositionalArgs =
false;
8064 bool atFirstArg =
true;
8065 bool inFunctionCall;
8067 llvm::SmallBitVector &CheckedVarArgs;
8068 UncoveredArgHandler &UncoveredArg;
8071 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
8073 unsigned firstDataArg,
unsigned numDataArgs,
8075 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8077 llvm::SmallBitVector &CheckedVarArgs,
8078 UncoveredArgHandler &UncoveredArg)
8079 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
8080 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
8081 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
8082 inFunctionCall(inFunctionCall), CallType(callType),
8083 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
8084 CoveredArgs.resize(numDataArgs);
8085 CoveredArgs.reset();
8088 bool HasFormatArguments()
const {
8093 void DoneProcessing();
8095 void HandleIncompleteSpecifier(
const char *startSpecifier,
8096 unsigned specifierLen)
override;
8098 void HandleInvalidLengthModifier(
8099 const analyze_format_string::FormatSpecifier &FS,
8100 const analyze_format_string::ConversionSpecifier &CS,
8101 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
8103 void HandleNonStandardLengthModifier(
8104 const analyze_format_string::FormatSpecifier &FS,
8105 const char *startSpecifier,
unsigned specifierLen);
8107 void HandleNonStandardConversionSpecifier(
8108 const analyze_format_string::ConversionSpecifier &CS,
8109 const char *startSpecifier,
unsigned specifierLen);
8111 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
8113 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
8116 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
8118 void HandleNullChar(
const char *nullCharacter)
override;
8120 template <
typename Range>
8122 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
8123 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
8124 bool IsStringLocation, Range StringRange,
8125 ArrayRef<FixItHint> Fixit = {});
8128 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
8129 const char *startSpec,
8130 unsigned specifierLen,
8131 const char *csStart,
unsigned csLen);
8133 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
8134 const char *startSpec,
8135 unsigned specifierLen);
8137 SourceRange getFormatStringRange();
8138 CharSourceRange getSpecifierRange(
const char *startSpecifier,
8139 unsigned specifierLen);
8140 SourceLocation getLocationOfByte(
const char *x);
8142 const Expr *getDataArg(
unsigned i)
const;
8144 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
8145 const analyze_format_string::ConversionSpecifier &CS,
8146 const char *startSpecifier,
unsigned specifierLen,
8149 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
8150 const Expr *E,
const char *startSpecifier,
8151 unsigned specifierLen);
8153 template <
typename Range>
8154 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
8155 bool IsStringLocation, Range StringRange,
8156 ArrayRef<FixItHint> Fixit = {});
8161SourceRange CheckFormatHandler::getFormatStringRange() {
8166CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8167 unsigned specifierLen) {
8169 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8177SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8182void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8183 unsigned specifierLen) {
8184 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8185 getLocationOfByte(startSpecifier),
8187 getSpecifierRange(startSpecifier, specifierLen));
8190bool CheckFormatHandler::CheckUnsupportedType(
8192 const char *StartSpecifier,
unsigned SpecifierLen) {
8196 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8199 getSpecifierRange(StartSpecifier, SpecifierLen));
8203void CheckFormatHandler::HandleInvalidLengthModifier(
8206 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8218 getSpecifierRange(startSpecifier, specifierLen));
8220 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8221 << FixedLM->toString()
8226 if (DiagID == diag::warn_format_nonsensical_length)
8232 getSpecifierRange(startSpecifier, specifierLen), Hint);
8236void CheckFormatHandler::HandleNonStandardLengthModifier(
8238 const char *startSpecifier,
unsigned specifierLen) {
8247 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8251 getSpecifierRange(startSpecifier, specifierLen));
8253 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8254 << FixedLM->toString()
8258 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8262 getSpecifierRange(startSpecifier, specifierLen));
8266void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8268 const char *startSpecifier,
unsigned specifierLen) {
8274 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8278 getSpecifierRange(startSpecifier, specifierLen));
8281 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8282 << FixedCS->toString()
8285 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8289 getSpecifierRange(startSpecifier, specifierLen));
8293void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8295 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8296 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8297 getLocationOfByte(startPos),
8299 getSpecifierRange(startPos, posLen));
8302void CheckFormatHandler::HandleInvalidPosition(
8303 const char *startSpecifier,
unsigned specifierLen,
8306 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8307 EmitFormatDiagnostic(
8308 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8309 getLocationOfByte(startSpecifier),
true,
8310 getSpecifierRange(startSpecifier, specifierLen));
8313void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8317 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8318 getLocationOfByte(startPos),
8320 getSpecifierRange(startPos, posLen));
8323void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8326 EmitFormatDiagnostic(
8327 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8328 getLocationOfByte(nullCharacter),
true,
8329 getFormatStringRange());
8335const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8336 return Args[FirstDataArg + i];
8339void CheckFormatHandler::DoneProcessing() {
8342 if (HasFormatArguments()) {
8345 signed notCoveredArg = CoveredArgs.find_first();
8346 if (notCoveredArg >= 0) {
8347 assert((
unsigned)notCoveredArg < NumDataArgs);
8348 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8350 UncoveredArg.setAllCovered();
8355void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8356 const Expr *ArgExpr) {
8357 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8368 for (
auto E : DiagnosticExprs)
8371 CheckFormatHandler::EmitFormatDiagnostic(
8372 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8376bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8378 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8379 bool keepGoing =
true;
8380 if (argIndex < NumDataArgs) {
8383 CoveredArgs.set(argIndex);
8398 std::string CodePointStr;
8399 if (!llvm::sys::locale::isPrint(*csStart)) {
8400 llvm::UTF32 CodePoint;
8401 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8402 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8403 llvm::ConversionResult
Result =
8404 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8406 if (
Result != llvm::conversionOK) {
8407 unsigned char FirstChar = *csStart;
8408 CodePoint = (llvm::UTF32)FirstChar;
8411 llvm::raw_string_ostream
OS(CodePointStr);
8412 if (CodePoint < 256)
8413 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8414 else if (CodePoint <= 0xFFFF)
8415 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8417 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8421 EmitFormatDiagnostic(
8422 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8423 true, getSpecifierRange(startSpec, specifierLen));
8428void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8429 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8430 EmitFormatDiagnostic(
8431 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8432 true, getSpecifierRange(startSpec, specifierLen));
8435bool CheckFormatHandler::CheckNumArgs(
8438 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8440 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8443 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8444 << (argIndex + 1) << NumDataArgs)
8445 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8446 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8448 getSpecifierRange(startSpecifier, specifierLen));
8452 UncoveredArg.setAllCovered();
8458template <
typename Range>
8461 bool IsStringLocation,
8464 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8465 IsStringLocation, StringRange, FixIt);
8495template <
typename Range>
8496void CheckFormatHandler::EmitFormatDiagnostic(
8497 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8500 if (InFunctionCall) {
8505 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8509 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8510 diag::note_format_string_defined);
8512 Note << StringRange;
8521class CheckPrintfHandler :
public CheckFormatHandler {
8523 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8525 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8527 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8529 llvm::SmallBitVector &CheckedVarArgs,
8530 UncoveredArgHandler &UncoveredArg)
8531 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8532 numDataArgs, beg, APK, Args, formatIdx,
8533 inFunctionCall, CallType, CheckedVarArgs,
8536 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8539 bool allowsObjCArg()
const {
8540 return FSType == FormatStringType::NSString ||
8541 FSType == FormatStringType::OSLog ||
8542 FSType == FormatStringType::OSTrace;
8545 bool HandleInvalidPrintfConversionSpecifier(
8546 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8547 unsigned specifierLen)
override;
8549 void handleInvalidMaskType(StringRef MaskType)
override;
8551 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8552 const char *startSpecifier,
unsigned specifierLen,
8553 const TargetInfo &
Target)
override;
8554 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8555 const char *StartSpecifier,
unsigned SpecifierLen,
8558 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8559 unsigned k,
const char *startSpecifier,
8560 unsigned specifierLen);
8561 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8562 const analyze_printf::OptionalAmount &Amt,
8563 unsigned type,
const char *startSpecifier,
8564 unsigned specifierLen);
8565 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8566 const analyze_printf::OptionalFlag &flag,
8567 const char *startSpecifier,
unsigned specifierLen);
8568 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8569 const analyze_printf::OptionalFlag &ignoredFlag,
8570 const analyze_printf::OptionalFlag &flag,
8571 const char *startSpecifier,
unsigned specifierLen);
8572 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8574 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8575 unsigned flagLen)
override;
8577 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8578 unsigned flagLen)
override;
8581 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8582 const char *flagsEnd,
8583 const char *conversionPosition)
override;
8588class EquatableFormatArgument {
8590 enum SpecifierSensitivity :
unsigned {
8597 enum FormatArgumentRole :
unsigned {
8605 analyze_format_string::ArgType ArgType;
8606 analyze_format_string::LengthModifier LengthMod;
8607 StringRef SpecifierLetter;
8608 CharSourceRange
Range;
8609 SourceLocation ElementLoc;
8610 FormatArgumentRole
Role : 2;
8611 SpecifierSensitivity Sensitivity : 2;
8612 unsigned Position : 14;
8613 unsigned ModifierFor : 14;
8615 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8616 bool InFunctionCall)
const;
8619 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8620 analyze_format_string::LengthModifier LengthMod,
8621 StringRef SpecifierLetter,
8622 analyze_format_string::ArgType ArgType,
8623 FormatArgumentRole
Role,
8624 SpecifierSensitivity Sensitivity,
unsigned Position,
8625 unsigned ModifierFor)
8626 : ArgType(ArgType), LengthMod(LengthMod),
8627 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8628 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8629 ModifierFor(ModifierFor) {}
8631 unsigned getPosition()
const {
return Position; }
8632 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8634 analyze_format_string::LengthModifier getLengthModifier()
const {
8637 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8639 std::string buildFormatSpecifier()
const {
8641 llvm::raw_string_ostream(result)
8642 << getLengthModifier().
toString() << SpecifierLetter;
8646 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8647 const Expr *FmtExpr,
bool InFunctionCall)
const;
8651class DecomposePrintfHandler :
public CheckPrintfHandler {
8652 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8655 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8656 const Expr *origFormatExpr,
8658 unsigned numDataArgs,
bool isObjC,
const char *beg,
8660 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8662 llvm::SmallBitVector &CheckedVarArgs,
8663 UncoveredArgHandler &UncoveredArg,
8664 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8665 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8666 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8667 inFunctionCall, CallType, CheckedVarArgs,
8669 Specs(Specs), HadError(
false) {}
8673 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8675 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8677 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8678 const char *startSpecifier,
8679 unsigned specifierLen,
8680 const TargetInfo &
Target)
override;
8685bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8687 unsigned specifierLen) {
8691 return HandleInvalidConversionSpecifier(
8696void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8697 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8705 return T->isRecordType() ||
T->isComplexType();
8708bool CheckPrintfHandler::HandleAmount(
8710 const char *startSpecifier,
unsigned specifierLen) {
8712 if (HasFormatArguments()) {
8714 if (argIndex >= NumDataArgs) {
8715 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8719 getSpecifierRange(startSpecifier, specifierLen));
8729 CoveredArgs.set(argIndex);
8730 const Expr *Arg = getDataArg(argIndex);
8741 ? diag::err_printf_asterisk_wrong_type
8742 : diag::warn_printf_asterisk_wrong_type;
8743 EmitFormatDiagnostic(S.
PDiag(DiagID)
8748 getSpecifierRange(startSpecifier, specifierLen));
8758void CheckPrintfHandler::HandleInvalidAmount(
8761 const char *startSpecifier,
unsigned specifierLen) {
8771 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8775 getSpecifierRange(startSpecifier, specifierLen), fixit);
8780 const char *startSpecifier,
8781 unsigned specifierLen) {
8785 EmitFormatDiagnostic(
8786 S.
PDiag(diag::warn_printf_nonsensical_flag)
8790 getSpecifierRange(startSpecifier, specifierLen),
8794void CheckPrintfHandler::HandleIgnoredFlag(
8798 unsigned specifierLen) {
8800 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8804 getSpecifierRange(startSpecifier, specifierLen),
8806 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8809void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8812 EmitFormatDiagnostic(
8813 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8814 true, getSpecifierRange(startFlag, flagLen));
8817void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8820 auto Range = getSpecifierRange(startFlag, flagLen);
8821 StringRef flag(startFlag, flagLen);
8822 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8823 getLocationOfByte(startFlag),
8828void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8829 const char *flagsStart,
const char *flagsEnd,
8830 const char *conversionPosition) {
8832 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8833 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8834 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8835 getLocationOfByte(conversionPosition),
8841 const Expr *FmtExpr,
8842 bool InFunctionCall)
const {
8843 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8844 ElementLoc,
true, Range);
8847bool EquatableFormatArgument::VerifyCompatible(
8848 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8849 bool InFunctionCall)
const {
8854 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8855 FmtExpr, InFunctionCall);
8856 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8860 if (
Role != FAR_Data) {
8861 if (ModifierFor !=
Other.ModifierFor) {
8864 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8865 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8866 FmtExpr, InFunctionCall);
8867 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8873 bool HadError =
false;
8874 if (Sensitivity !=
Other.Sensitivity) {
8877 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8878 << Sensitivity <<
Other.Sensitivity,
8879 FmtExpr, InFunctionCall);
8880 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8881 << 0 <<
Other.Range;
8884 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8888 case MK::MatchPromotion:
8892 case MK::NoMatchTypeConfusion:
8893 case MK::NoMatchPromotionTypeConfusion:
8895 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8896 << buildFormatSpecifier()
8897 <<
Other.buildFormatSpecifier(),
8898 FmtExpr, InFunctionCall);
8899 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8900 << 0 <<
Other.Range;
8903 case MK::NoMatchPedantic:
8905 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8906 << buildFormatSpecifier()
8907 <<
Other.buildFormatSpecifier(),
8908 FmtExpr, InFunctionCall);
8909 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8910 << 0 <<
Other.Range;
8913 case MK::NoMatchSignedness:
8915 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8916 << buildFormatSpecifier()
8917 <<
Other.buildFormatSpecifier(),
8918 FmtExpr, InFunctionCall);
8919 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8920 << 0 <<
Other.Range;
8926bool DecomposePrintfHandler::GetSpecifiers(
8927 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8930 StringRef
Data = FSL->getString();
8931 const char *Str =
Data.data();
8932 llvm::SmallBitVector BV;
8933 UncoveredArgHandler UA;
8934 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8935 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8947 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8948 const EquatableFormatArgument &B) {
8949 return A.getPosition() < B.getPosition();
8954bool DecomposePrintfHandler::HandlePrintfSpecifier(
8957 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8972 const unsigned Unset = ~0;
8973 unsigned FieldWidthIndex = Unset;
8974 unsigned PrecisionIndex = Unset;
8978 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8979 FieldWidthIndex = Specs.size();
8981 getSpecifierRange(startSpecifier, specifierLen),
8982 getLocationOfByte(FieldWidth.getStart()),
8984 FieldWidth.getArgType(S.
Context),
8985 EquatableFormatArgument::FAR_FieldWidth,
8986 EquatableFormatArgument::SS_None,
8987 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
8993 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8994 PrecisionIndex = Specs.size();
8996 getSpecifierRange(startSpecifier, specifierLen),
8997 getLocationOfByte(Precision.getStart()),
8999 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
9000 EquatableFormatArgument::SS_None,
9001 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
9007 unsigned SpecIndex =
9009 if (FieldWidthIndex != Unset)
9010 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
9011 if (PrecisionIndex != Unset)
9012 Specs[PrecisionIndex].setModifierFor(SpecIndex);
9014 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
9016 Sensitivity = EquatableFormatArgument::SS_Private;
9018 Sensitivity = EquatableFormatArgument::SS_Public;
9020 Sensitivity = EquatableFormatArgument::SS_Sensitive;
9022 Sensitivity = EquatableFormatArgument::SS_None;
9025 getSpecifierRange(startSpecifier, specifierLen),
9028 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
9033 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
9038 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
9039 SpecIndex + 1, SpecIndex);
9047template<
typename MemberKind>
9058 R.suppressDiagnostics();
9065 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
9080 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9082 if ((*MI)->getMinRequiredArguments() == 0)
9090bool CheckPrintfHandler::checkForCStrMembers(
9097 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9100 if (
Method->getMinRequiredArguments() == 0 &&
9113bool CheckPrintfHandler::HandlePrintfSpecifier(
9126 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
9127 startSpecifier, specifierLen);
9139 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
9144 if (!CS.consumesDataArgument()) {
9152 if (argIndex < NumDataArgs) {
9156 CoveredArgs.set(argIndex);
9163 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9166 if (HasFormatArguments()) {
9168 CoveredArgs.set(argIndex + 1);
9171 const Expr *Ex = getDataArg(argIndex);
9175 : ArgType::CPointerTy;
9177 EmitFormatDiagnostic(
9178 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9182 getSpecifierRange(startSpecifier, specifierLen));
9185 Ex = getDataArg(argIndex + 1);
9188 EmitFormatDiagnostic(
9189 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9193 getSpecifierRange(startSpecifier, specifierLen));
9200 if (!allowsObjCArg() && CS.isObjCArg()) {
9201 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9208 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9215 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9216 getLocationOfByte(CS.getStart()),
9218 getSpecifierRange(startSpecifier, specifierLen));
9228 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9235 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9239 getSpecifierRange(startSpecifier, specifierLen));
9242 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9246 getSpecifierRange(startSpecifier, specifierLen));
9250 const llvm::Triple &Triple =
Target.getTriple();
9252 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9253 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9254 getLocationOfByte(CS.getStart()),
9256 getSpecifierRange(startSpecifier, specifierLen));
9262 startSpecifier, specifierLen);
9268 startSpecifier, specifierLen);
9274 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9275 getLocationOfByte(startSpecifier),
9277 getSpecifierRange(startSpecifier, specifierLen));
9286 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9288 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9297 startSpecifier, specifierLen);
9300 startSpecifier, specifierLen);
9305 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9306 diag::warn_format_nonsensical_length);
9308 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9310 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9311 diag::warn_format_non_standard_conversion_spec);
9314 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9317 if (!HasFormatArguments())
9320 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9323 const Expr *Arg = getDataArg(argIndex);
9327 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9339 case Stmt::ArraySubscriptExprClass:
9340 case Stmt::CallExprClass:
9341 case Stmt::CharacterLiteralClass:
9342 case Stmt::CXXBoolLiteralExprClass:
9343 case Stmt::DeclRefExprClass:
9344 case Stmt::FloatingLiteralClass:
9345 case Stmt::IntegerLiteralClass:
9346 case Stmt::MemberExprClass:
9347 case Stmt::ObjCArrayLiteralClass:
9348 case Stmt::ObjCBoolLiteralExprClass:
9349 case Stmt::ObjCBoxedExprClass:
9350 case Stmt::ObjCDictionaryLiteralClass:
9351 case Stmt::ObjCEncodeExprClass:
9352 case Stmt::ObjCIvarRefExprClass:
9353 case Stmt::ObjCMessageExprClass:
9354 case Stmt::ObjCPropertyRefExprClass:
9355 case Stmt::ObjCStringLiteralClass:
9356 case Stmt::ObjCSubscriptRefExprClass:
9357 case Stmt::ParenExprClass:
9358 case Stmt::StringLiteralClass:
9359 case Stmt::UnaryOperatorClass:
9366static std::pair<QualType, StringRef>
9372 StringRef Name = UserTy->getDecl()->getName();
9373 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9374 .Case(
"CFIndex", Context.getNSIntegerType())
9375 .Case(
"NSInteger", Context.getNSIntegerType())
9376 .Case(
"NSUInteger", Context.getNSUIntegerType())
9377 .Case(
"SInt32", Context.IntTy)
9378 .Case(
"UInt32", Context.UnsignedIntTy)
9382 return std::make_pair(CastTy, Name);
9384 TyTy = UserTy->desugar();
9388 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9398 StringRef TrueName, FalseName;
9401 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9403 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9405 if (TrueTy == FalseTy)
9406 return std::make_pair(TrueTy, TrueName);
9407 else if (TrueTy.
isNull())
9408 return std::make_pair(FalseTy, FalseName);
9409 else if (FalseTy.
isNull())
9410 return std::make_pair(TrueTy, TrueName);
9413 return std::make_pair(
QualType(), StringRef());
9432 From = VecTy->getElementType();
9434 To = VecTy->getElementType();
9445 diag::warn_format_conversion_argument_type_mismatch_signedness,
9449 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9456bool CheckPrintfHandler::checkFormatExpr(
9458 unsigned SpecifierLen,
const Expr *E) {
9469 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9470 ExprTy = TET->getUnderlyingExpr()->getType();
9473 if (
const OverflowBehaviorType *OBT =
9475 ExprTy = OBT->getUnderlyingType();
9489 getSpecifierRange(StartSpecifier, SpecifierLen);
9491 llvm::raw_svector_ostream os(FSString);
9493 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9504 getSpecifierRange(StartSpecifier, SpecifierLen);
9505 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9510 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9518 if (
Match == ArgType::Match)
9522 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9531 E = ICE->getSubExpr();
9541 if (OrigMatch == ArgType::NoMatchSignedness &&
9542 ImplicitMatch != ArgType::NoMatchSignedness)
9549 if (ImplicitMatch == ArgType::Match)
9567 if (
Match == ArgType::MatchPromotion)
9571 if (
Match == ArgType::MatchPromotion) {
9575 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9576 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9580 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9581 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9582 Match = ImplicitMatch;
9583 assert(
Match != ArgType::MatchPromotion);
9586 bool IsEnum =
false;
9587 bool IsScopedEnum =
false;
9590 IntendedTy = ED->getIntegerType();
9591 if (!ED->isScoped()) {
9592 ExprTy = IntendedTy;
9597 IsScopedEnum =
true;
9604 if (isObjCContext() &&
9615 const llvm::APInt &
V = IL->getValue();
9625 if (TD->getUnderlyingType() == IntendedTy)
9635 bool ShouldNotPrintDirectly =
false;
9636 StringRef CastTyName;
9639 std::tie(CastTy, CastTyName) =
9645 if (!IsScopedEnum &&
9646 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9650 IntendedTy = CastTy;
9651 ShouldNotPrintDirectly =
true;
9656 PrintfSpecifier fixedFS = FS;
9663 llvm::raw_svector_ostream os(buf);
9666 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9668 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9674 llvm_unreachable(
"expected non-matching");
9676 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9679 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9682 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9685 Diag = diag::warn_format_conversion_argument_type_mismatch;
9706 llvm::raw_svector_ostream CastFix(CastBuf);
9707 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9709 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9715 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9720 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9742 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9748 Name = TypedefTy->getDecl()->getName();
9752 ? diag::warn_format_argument_needs_cast_pedantic
9753 : diag::warn_format_argument_needs_cast;
9754 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9765 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9766 : diag::warn_format_conversion_argument_type_mismatch;
9768 EmitFormatDiagnostic(
9776 getSpecifierRange(StartSpecifier, SpecifierLen);
9780 bool EmitTypeMismatch =
false;
9784 bool EmitOSLogError =
false;
9793 llvm_unreachable(
"expected non-matching");
9795 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9798 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9801 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9805 Diag = diag::warn_format_conversion_argument_type_mismatch;
9809 if (!EmitOSLogError)
9810 EmitFormatDiagnostic(
9819 EmitTypeMismatch =
true;
9823 EmitOSLogError =
true;
9825 EmitFormatDiagnostic(
9826 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9827 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9831 checkForCStrMembers(AT, E);
9837 EmitTypeMismatch =
true;
9839 EmitFormatDiagnostic(
9840 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9841 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9855 EmitFormatDiagnostic(
9856 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
9861 if (EmitTypeMismatch) {
9867 EmitFormatDiagnostic(
9868 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9874 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9875 "format string specifier index out of range");
9876 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9886class CheckScanfHandler :
public CheckFormatHandler {
9888 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
9890 unsigned firstDataArg,
unsigned numDataArgs,
9892 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9894 llvm::SmallBitVector &CheckedVarArgs,
9895 UncoveredArgHandler &UncoveredArg)
9896 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
9897 numDataArgs, beg, APK, Args, formatIdx,
9898 inFunctionCall, CallType, CheckedVarArgs,
9901 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9902 const char *startSpecifier,
9903 unsigned specifierLen)
override;
9906 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9907 const char *startSpecifier,
9908 unsigned specifierLen)
override;
9910 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9915void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9917 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9918 getLocationOfByte(end),
true,
9919 getSpecifierRange(start, end - start));
9922bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9924 unsigned specifierLen) {
9928 return HandleInvalidConversionSpecifier(
9933bool CheckScanfHandler::HandleScanfSpecifier(
9935 unsigned specifierLen) {
9948 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9949 startSpecifier, specifierLen);
9960 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9975 if (argIndex < NumDataArgs) {
9979 CoveredArgs.set(argIndex);
9985 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9986 diag::warn_format_nonsensical_length);
9988 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9990 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9991 diag::warn_format_non_standard_conversion_spec);
9994 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9997 if (!HasFormatArguments())
10000 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
10004 const Expr *Ex = getDataArg(argIndex);
10014 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
10025 ScanfSpecifier fixedFS = FS;
10030 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
10032 ? diag::warn_format_conversion_argument_type_mismatch_signedness
10033 : diag::warn_format_conversion_argument_type_mismatch;
10038 llvm::raw_svector_ostream os(buf);
10041 EmitFormatDiagnostic(
10046 getSpecifierRange(startSpecifier, specifierLen),
10048 getSpecifierRange(startSpecifier, specifierLen), os.str()));
10055 getSpecifierRange(startSpecifier, specifierLen));
10065 const Expr *FmtExpr,
bool InFunctionCall) {
10066 bool HadError =
false;
10067 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
10068 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
10069 while (FmtIter < FmtEnd && RefIter < RefEnd) {
10081 for (; FmtIter < FmtEnd; ++FmtIter) {
10085 if (FmtIter->getPosition() < RefIter->getPosition())
10089 if (FmtIter->getPosition() > RefIter->getPosition())
10093 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
10097 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
10098 return Arg.getPosition() != RefIter->getPosition();
10102 if (FmtIter < FmtEnd) {
10103 CheckFormatHandler::EmitFormatDiagnostic(
10104 S, InFunctionCall, FmtExpr,
10105 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
10106 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
10107 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
10108 }
else if (RefIter < RefEnd) {
10109 CheckFormatHandler::EmitFormatDiagnostic(
10110 S, InFunctionCall, FmtExpr,
10111 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
10114 << 1 << RefIter->getSourceRange();
10120 Sema &S,
const FormatStringLiteral *FExpr,
10125 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
10126 bool IgnoreStringsWithoutSpecifiers) {
10128 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
10129 CheckFormatHandler::EmitFormatDiagnostic(
10130 S, inFunctionCall, Args[format_idx],
10131 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
10137 StringRef StrRef = FExpr->getString();
10138 const char *Str = StrRef.data();
10142 assert(
T &&
"String literal not of constant array type!");
10143 size_t TypeSize =
T->getZExtSize();
10144 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10145 const unsigned numDataArgs = Args.size() - firstDataArg;
10147 if (IgnoreStringsWithoutSpecifiers &&
10154 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
10155 CheckFormatHandler::EmitFormatDiagnostic(
10156 S, inFunctionCall, Args[format_idx],
10157 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
10158 FExpr->getBeginLoc(),
10164 if (StrLen == 0 && numDataArgs > 0) {
10165 CheckFormatHandler::EmitFormatDiagnostic(
10166 S, inFunctionCall, Args[format_idx],
10167 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10178 if (ReferenceFormatString ==
nullptr) {
10179 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10180 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10181 inFunctionCall, CallType, CheckedVarArgs,
10188 H.DoneProcessing();
10191 Type, ReferenceFormatString, FExpr->getFormatString(),
10192 inFunctionCall ?
nullptr : Args[format_idx]);
10195 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10196 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10197 CallType, CheckedVarArgs, UncoveredArg);
10201 H.DoneProcessing();
10217 FormatStringLiteral RefLit = AuthoritativeFormatString;
10218 FormatStringLiteral TestLit = TestedFormatString;
10220 bool DiagAtStringLiteral;
10221 if (FunctionCallArg) {
10222 Arg = FunctionCallArg;
10223 DiagAtStringLiteral =
false;
10225 Arg = TestedFormatString;
10226 DiagAtStringLiteral =
true;
10228 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10229 AuthoritativeFormatString,
Type,
10230 IsObjC,
true, RefArgs) &&
10231 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10232 DiagAtStringLiteral, FmtArgs)) {
10234 TestedFormatString, FmtArgs, Arg,
10235 DiagAtStringLiteral);
10248 FormatStringLiteral RefLit = Str;
10252 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10261 bool HadError =
false;
10262 auto Iter = Args.begin();
10263 auto End = Args.end();
10264 while (Iter != End) {
10265 const auto &FirstInGroup = *Iter;
10267 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10269 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10278 const char *Str = StrRef.data();
10281 assert(
T &&
"String literal not of constant array type!");
10282 size_t TypeSize =
T->getZExtSize();
10283 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10293 switch (AbsFunction) {
10297 case Builtin::BI__builtin_abs:
10298 return Builtin::BI__builtin_labs;
10299 case Builtin::BI__builtin_labs:
10300 return Builtin::BI__builtin_llabs;
10301 case Builtin::BI__builtin_llabs:
10304 case Builtin::BI__builtin_fabsf:
10305 return Builtin::BI__builtin_fabs;
10306 case Builtin::BI__builtin_fabs:
10307 return Builtin::BI__builtin_fabsl;
10308 case Builtin::BI__builtin_fabsl:
10311 case Builtin::BI__builtin_cabsf:
10312 return Builtin::BI__builtin_cabs;
10313 case Builtin::BI__builtin_cabs:
10314 return Builtin::BI__builtin_cabsl;
10315 case Builtin::BI__builtin_cabsl:
10318 case Builtin::BIabs:
10319 return Builtin::BIlabs;
10320 case Builtin::BIlabs:
10321 return Builtin::BIllabs;
10322 case Builtin::BIllabs:
10325 case Builtin::BIfabsf:
10326 return Builtin::BIfabs;
10327 case Builtin::BIfabs:
10328 return Builtin::BIfabsl;
10329 case Builtin::BIfabsl:
10332 case Builtin::BIcabsf:
10333 return Builtin::BIcabs;
10334 case Builtin::BIcabs:
10335 return Builtin::BIcabsl;
10336 case Builtin::BIcabsl:
10343 unsigned AbsType) {
10365 unsigned AbsFunctionKind) {
10366 unsigned BestKind = 0;
10367 uint64_t ArgSize = Context.getTypeSize(ArgType);
10368 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10371 if (Context.getTypeSize(ParamType) >= ArgSize) {
10374 else if (Context.hasSameType(ParamType, ArgType)) {
10390 if (
T->isIntegralOrEnumerationType())
10392 if (
T->isRealFloatingType())
10394 if (
T->isAnyComplexType())
10397 llvm_unreachable(
"Type not integer, floating, or complex");
10404 switch (ValueKind) {
10409 case Builtin::BI__builtin_fabsf:
10410 case Builtin::BI__builtin_fabs:
10411 case Builtin::BI__builtin_fabsl:
10412 case Builtin::BI__builtin_cabsf:
10413 case Builtin::BI__builtin_cabs:
10414 case Builtin::BI__builtin_cabsl:
10415 return Builtin::BI__builtin_abs;
10416 case Builtin::BIfabsf:
10417 case Builtin::BIfabs:
10418 case Builtin::BIfabsl:
10419 case Builtin::BIcabsf:
10420 case Builtin::BIcabs:
10421 case Builtin::BIcabsl:
10422 return Builtin::BIabs;
10428 case Builtin::BI__builtin_abs:
10429 case Builtin::BI__builtin_labs:
10430 case Builtin::BI__builtin_llabs:
10431 case Builtin::BI__builtin_cabsf:
10432 case Builtin::BI__builtin_cabs:
10433 case Builtin::BI__builtin_cabsl:
10434 return Builtin::BI__builtin_fabsf;
10435 case Builtin::BIabs:
10436 case Builtin::BIlabs:
10437 case Builtin::BIllabs:
10438 case Builtin::BIcabsf:
10439 case Builtin::BIcabs:
10440 case Builtin::BIcabsl:
10441 return Builtin::BIfabsf;
10447 case Builtin::BI__builtin_abs:
10448 case Builtin::BI__builtin_labs:
10449 case Builtin::BI__builtin_llabs:
10450 case Builtin::BI__builtin_fabsf:
10451 case Builtin::BI__builtin_fabs:
10452 case Builtin::BI__builtin_fabsl:
10453 return Builtin::BI__builtin_cabsf;
10454 case Builtin::BIabs:
10455 case Builtin::BIlabs:
10456 case Builtin::BIllabs:
10457 case Builtin::BIfabsf:
10458 case Builtin::BIfabs:
10459 case Builtin::BIfabsl:
10460 return Builtin::BIcabsf;
10463 llvm_unreachable(
"Unable to convert function");
10474 case Builtin::BI__builtin_abs:
10475 case Builtin::BI__builtin_fabs:
10476 case Builtin::BI__builtin_fabsf:
10477 case Builtin::BI__builtin_fabsl:
10478 case Builtin::BI__builtin_labs:
10479 case Builtin::BI__builtin_llabs:
10480 case Builtin::BI__builtin_cabs:
10481 case Builtin::BI__builtin_cabsf:
10482 case Builtin::BI__builtin_cabsl:
10483 case Builtin::BIabs:
10484 case Builtin::BIlabs:
10485 case Builtin::BIllabs:
10486 case Builtin::BIfabs:
10487 case Builtin::BIfabsf:
10488 case Builtin::BIfabsl:
10489 case Builtin::BIcabs:
10490 case Builtin::BIcabsf:
10491 case Builtin::BIcabsl:
10494 llvm_unreachable(
"Unknown Builtin type");
10500 unsigned AbsKind,
QualType ArgType) {
10501 bool EmitHeaderHint =
true;
10502 const char *HeaderName =
nullptr;
10503 std::string FunctionName;
10504 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10505 FunctionName =
"std::abs";
10506 if (ArgType->isIntegralOrEnumerationType()) {
10507 HeaderName =
"cstdlib";
10508 }
else if (ArgType->isRealFloatingType()) {
10509 HeaderName =
"cmath";
10511 llvm_unreachable(
"Invalid Type");
10517 R.suppressDiagnostics();
10520 for (
const auto *I : R) {
10523 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10525 FDecl = dyn_cast<FunctionDecl>(I);
10540 EmitHeaderHint =
false;
10552 R.suppressDiagnostics();
10555 if (R.isSingleResult()) {
10556 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10558 EmitHeaderHint =
false;
10562 }
else if (!R.empty()) {
10568 S.
Diag(Loc, diag::note_replace_abs_function)
10574 if (!EmitHeaderHint)
10577 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10581template <std::
size_t StrLen>
10583 const char (&Str)[StrLen]) {
10596 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10597 return llvm::is_contained(names, calleeName);
10602 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10603 "__builtin_nanf16",
"__builtin_nanf128"});
10605 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10606 "__builtin_inff16",
"__builtin_inff128"});
10608 llvm_unreachable(
"unknown MathCheck");
10612 if (FDecl->
getName() !=
"infinity")
10615 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10617 if (RDecl->
getName() !=
"numeric_limits")
10634 if (FPO.getNoHonorNaNs() &&
10637 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10638 << 1 << 0 <<
Call->getSourceRange();
10642 if (FPO.getNoHonorInfs() &&
10646 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10647 << 0 << 0 <<
Call->getSourceRange();
10651void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10653 if (
Call->getNumArgs() != 1)
10658 if (AbsKind == 0 && !IsStdAbs)
10661 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10662 QualType ParamType =
Call->getArg(0)->getType();
10667 std::string FunctionName =
10668 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10669 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10670 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10705 if (ArgValueKind == ParamValueKind) {
10706 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10710 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10711 << FDecl << ArgType << ParamType;
10713 if (NewAbsKind == 0)
10717 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10726 if (NewAbsKind == 0)
10729 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10730 << FDecl << ParamValueKind << ArgValueKind;
10733 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10739 if (!
Call || !FDecl)
return;
10743 if (
Call->getExprLoc().isMacroID())
return;
10746 if (
Call->getNumArgs() != 2)
return;
10749 if (!ArgList)
return;
10750 if (ArgList->size() != 1)
return;
10753 const auto& TA = ArgList->
get(0);
10755 QualType ArgType = TA.getAsType();
10759 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10760 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10761 if (!MTE)
return false;
10762 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10763 if (!
Num)
return false;
10764 if (
Num->getValue() != 0)
return false;
10768 const Expr *FirstArg =
Call->getArg(0);
10769 const Expr *SecondArg =
Call->getArg(1);
10770 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10771 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10774 if (IsFirstArgZero == IsSecondArgZero)
return;
10779 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10781 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10782 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10785 SourceRange RemovalRange;
10786 if (IsFirstArgZero) {
10787 RemovalRange = SourceRange(FirstRange.
getBegin(),
10794 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10809 const auto *Size = dyn_cast<BinaryOperator>(E);
10814 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10818 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10819 << SizeRange << FnName;
10820 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10825 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10836 bool &IsContained) {
10838 const Type *Ty =
T->getBaseElementTypeUnsafe();
10839 IsContained =
false;
10852 for (
auto *FD : RD->
fields()) {
10856 IsContained =
true;
10857 return ContainedRD;
10865 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10866 if (Unary->getKind() == UETT_SizeOf)
10875 if (!
SizeOf->isArgumentType())
10876 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10883 return SizeOf->getTypeOfArgument();
10889struct SearchNonTrivialToInitializeField
10892 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10894 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10897 SourceLocation SL) {
10898 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10899 asDerived().visitArray(PDIK, AT, SL);
10903 Super::visitWithKind(PDIK, FT, SL);
10906 void visitARCStrong(QualType FT, SourceLocation SL) {
10909 void visitARCWeak(QualType FT, SourceLocation SL) {
10912 void visitStruct(QualType FT, SourceLocation SL) {
10917 const ArrayType *AT, SourceLocation SL) {
10918 visit(getContext().getBaseElementType(AT), SL);
10920 void visitTrivial(QualType FT, SourceLocation SL) {}
10922 static void diag(QualType RT,
const Expr *E, Sema &S) {
10923 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10932struct SearchNonTrivialToCopyField
10934 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10936 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10939 SourceLocation SL) {
10940 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10941 asDerived().visitArray(PCK, AT, SL);
10945 Super::visitWithKind(PCK, FT, SL);
10948 void visitARCStrong(QualType FT, SourceLocation SL) {
10951 void visitARCWeak(QualType FT, SourceLocation SL) {
10954 void visitPtrAuth(QualType FT, SourceLocation SL) {
10957 void visitStruct(QualType FT, SourceLocation SL) {
10962 SourceLocation SL) {
10963 visit(getContext().getBaseElementType(AT), SL);
10966 SourceLocation SL) {}
10967 void visitTrivial(QualType FT, SourceLocation SL) {}
10968 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10970 static void diag(QualType RT,
const Expr *E, Sema &S) {
10971 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10986 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10987 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
11020 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
11023 const Expr *SizeArg =
11024 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
11026 auto isLiteralZero = [](
const Expr *E) {
11036 if (isLiteralZero(SizeArg) &&
11043 if (BId == Builtin::BIbzero ||
11046 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
11047 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
11048 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
11049 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
11050 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
11058 if (BId == Builtin::BImemset &&
11062 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
11063 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
11068void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
11075 unsigned ExpectedNumArgs =
11076 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
11077 if (
Call->getNumArgs() < ExpectedNumArgs)
11080 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
11081 BId == Builtin::BIstrndup ? 1 : 2);
11083 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
11087 Call->getBeginLoc(),
Call->getRParenLoc()))
11099 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
11100 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
11103 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
11107 QualType DestTy = Dest->
getType();
11108 QualType PointeeTy;
11109 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
11121 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
11127 if (SizeOfArgTy != QualType()) {
11129 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
11131 PDiag(diag::warn_sizeof_pointer_type_memaccess)
11132 << FnName << SizeOfArgTy << ArgIdx
11139 PointeeTy = DestTy;
11142 if (PointeeTy == QualType())
11147 if (
const CXXRecordDecl *ContainedRD =
11150 unsigned OperationType = 0;
11151 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
11154 if (ArgIdx != 0 || IsCmp) {
11155 if (BId == Builtin::BImemcpy)
11157 else if(BId == Builtin::BImemmove)
11164 PDiag(diag::warn_dyn_class_memaccess)
11165 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
11166 << IsContained << ContainedRD << OperationType
11167 <<
Call->getCallee()->getSourceRange());
11169 BId != Builtin::BImemset)
11172 PDiag(diag::warn_arc_object_memaccess)
11173 << ArgIdx << FnName << PointeeTy
11174 <<
Call->getCallee()->getSourceRange());
11181 bool NonTriviallyCopyableCXXRecord =
11185 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11188 PDiag(diag::warn_cstruct_memaccess)
11189 << ArgIdx << FnName << PointeeTy << 0);
11190 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11191 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11192 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11196 PDiag(diag::warn_cxxstruct_memaccess)
11197 << FnName << PointeeTy);
11198 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11201 PDiag(diag::warn_cstruct_memaccess)
11202 << ArgIdx << FnName << PointeeTy << 1);
11203 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11204 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11205 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11209 PDiag(diag::warn_cxxstruct_memaccess)
11210 << FnName << PointeeTy);
11219 PDiag(diag::note_bad_memaccess_silence)
11225bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11227 llvm::FoldingSetNodeID SizeOfArgID;
11233 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11236 QualType DestTy = Dest->
getType();
11237 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11243 if (SizeOfArgID == llvm::FoldingSetNodeID())
11246 llvm::FoldingSetNodeID DestID;
11248 if (DestID == SizeOfArgID) {
11251 unsigned ActionIdx = 0;
11252 StringRef ReadableName = FnName->
getName();
11254 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11255 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11264 SourceLocation SL = SizeOfArg->
getExprLoc();
11279 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11280 << ReadableName << PointeeTy << DestTy << DSR
11283 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11284 << ActionIdx << SSR);
11320 if (CAT->getZExtSize() <= 1)
11328void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11332 unsigned NumArgs =
Call->getNumArgs();
11333 if ((NumArgs != 3) && (NumArgs != 4))
11338 const Expr *CompareWithSrc =
nullptr;
11341 Call->getBeginLoc(),
Call->getRParenLoc()))
11346 CompareWithSrc = Ex;
11349 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11350 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11351 SizeCall->getNumArgs() == 1)
11356 if (!CompareWithSrc)
11363 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11367 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11368 if (!CompareWithSrcDRE ||
11372 const Expr *OriginalSizeArg =
Call->getArg(2);
11373 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11380 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11384 SmallString<128> sizeString;
11385 llvm::raw_svector_ostream
OS(sizeString);
11390 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11397 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11398 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11399 return D1->getDecl() == D2->getDecl();
11404 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11413void Sema::CheckStrncatArguments(
const CallExpr *CE,
11428 unsigned PatternType = 0;
11436 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11437 if (BE->getOpcode() == BO_Sub) {
11438 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11439 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11450 if (PatternType == 0)
11466 QualType DstTy = DstArg->
getType();
11469 if (!isKnownSizeArray) {
11470 if (PatternType == 1)
11471 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11473 Diag(SL, diag::warn_strncat_src_size) << SR;
11477 if (PatternType == 1)
11478 Diag(SL, diag::warn_strncat_large_size) << SR;
11480 Diag(SL, diag::warn_strncat_src_size) << SR;
11482 SmallString<128> sizeString;
11483 llvm::raw_svector_ostream
OS(sizeString);
11491 Diag(SL, diag::note_strncat_wrong_size)
11496void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11505void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11507 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11508 const Decl *D = Lvalue->getDecl();
11509 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11510 if (!DD->getType()->isReferenceType())
11511 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11515 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11516 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11517 Lvalue->getMemberDecl());
11520void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11522 const auto *Lambda = dyn_cast<LambdaExpr>(
11527 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11528 << CalleeName << 2 ;
11531void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11533 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11534 if (Var ==
nullptr)
11538 << CalleeName << 0 << Var;
11541void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11544 llvm::raw_svector_ostream
OS(SizeString);
11547 if (Kind == clang::CK_BitCast &&
11548 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11550 if (Kind == clang::CK_IntegralToPointer &&
11552 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11555 switch (
Cast->getCastKind()) {
11556 case clang::CK_BitCast:
11557 case clang::CK_IntegralToPointer:
11558 case clang::CK_FunctionToPointerDecay:
11567 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11568 << CalleeName << 0 <<
OS.str();
11572void Sema::CheckFreeArguments(
const CallExpr *E) {
11573 const std::string CalleeName =
11578 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11580 case UnaryOperator::Opcode::UO_AddrOf:
11581 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11582 case UnaryOperator::Opcode::UO_Plus:
11583 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11588 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11590 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11592 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11593 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11594 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11600 << CalleeName << 1 ;
11605 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11606 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11610Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11619 Diag(ReturnLoc, diag::warn_null_ret)
11629 if (Op == OO_New || Op == OO_Array_New) {
11630 const FunctionProtoType *Proto
11634 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11640 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11645 if (
Context.getTargetInfo().getTriple().isPPC64())
11657 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11658 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11659 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11660 return FPLiteral && FPCast;
11663 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11669 llvm::APFloat TargetC = FPLiteral->
getValue();
11670 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11671 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11675 Diag(Loc, diag::warn_float_compare_literal)
11676 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11689 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11690 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11691 if (DRL->getDecl() == DRR->getDecl())
11699 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11700 if (FLL->isExact())
11702 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11703 if (FLR->isExact())
11707 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11708 CL &&
CL->getBuiltinCallee())
11711 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11712 CR && CR->getBuiltinCallee())
11716 Diag(Loc, diag::warn_floatingpoint_eq)
11737 IntRange(
unsigned Width,
bool NonNegative)
11738 : Width(Width), NonNegative(NonNegative) {}
11741 unsigned valueBits()
const {
11742 return NonNegative ? Width : Width - 1;
11746 static IntRange forBoolType() {
11747 return IntRange(1,
true);
11751 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11752 return forValueOfCanonicalType(
C,
11757 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11760 if (
const auto *VT = dyn_cast<VectorType>(
T))
11761 T = VT->getElementType().getTypePtr();
11762 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11763 T = MT->getElementType().getTypePtr();
11764 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11765 T = CT->getElementType().getTypePtr();
11766 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11767 T = AT->getValueType().getTypePtr();
11768 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11769 T = OBT->getUnderlyingType().getTypePtr();
11771 if (!
C.getLangOpts().CPlusPlus) {
11774 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11779 if (
Enum->isFixed()) {
11780 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11781 !
Enum->getIntegerType()->isSignedIntegerType());
11784 unsigned NumPositive =
Enum->getNumPositiveBits();
11785 unsigned NumNegative =
Enum->getNumNegativeBits();
11787 if (NumNegative == 0)
11788 return IntRange(NumPositive,
true);
11790 return IntRange(std::max(NumPositive + 1, NumNegative),
11794 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11795 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11808 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11811 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11812 T = VT->getElementType().getTypePtr();
11813 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11814 T = MT->getElementType().getTypePtr();
11815 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11816 T = CT->getElementType().getTypePtr();
11817 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11818 T = AT->getValueType().getTypePtr();
11820 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11821 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11822 T = OBT->getUnderlyingType().getTypePtr();
11824 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11825 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11834 static IntRange
join(IntRange L, IntRange R) {
11835 bool Unsigned = L.NonNegative &&
R.NonNegative;
11836 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11837 L.NonNegative &&
R.NonNegative);
11841 static IntRange bit_and(IntRange L, IntRange R) {
11842 unsigned Bits = std::max(L.Width,
R.Width);
11843 bool NonNegative =
false;
11844 if (L.NonNegative) {
11845 Bits = std::min(Bits, L.Width);
11846 NonNegative =
true;
11848 if (
R.NonNegative) {
11849 Bits = std::min(Bits,
R.Width);
11850 NonNegative =
true;
11852 return IntRange(Bits, NonNegative);
11856 static IntRange sum(IntRange L, IntRange R) {
11857 bool Unsigned = L.NonNegative &&
R.NonNegative;
11858 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11863 static IntRange difference(IntRange L, IntRange R) {
11867 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11868 bool Unsigned = L.NonNegative &&
R.Width == 0;
11869 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11875 static IntRange product(IntRange L, IntRange R) {
11879 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11880 bool Unsigned = L.NonNegative &&
R.NonNegative;
11881 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11886 static IntRange rem(IntRange L, IntRange R) {
11890 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11898 if (value.isSigned() && value.isNegative())
11899 return IntRange(value.getSignificantBits(),
false);
11901 if (value.getBitWidth() > MaxWidth)
11902 value = value.trunc(MaxWidth);
11906 return IntRange(value.getActiveBits(),
true);
11910 if (result.
isInt())
11917 R = IntRange::join(R, El);
11925 return IntRange::join(R, I);
11940 Ty = AtomicRHS->getValueType();
11959 bool InConstantContext,
11960 bool Approximate) {
11971 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11972 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11976 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11978 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11979 CE->getCastKind() == CK_BooleanToSignedIntegral;
11982 if (!isIntegerCast)
11983 return OutputTypeRange;
11986 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11987 InConstantContext, Approximate);
11989 return std::nullopt;
11992 if (SubRange->Width >= OutputTypeRange.Width)
11993 return OutputTypeRange;
11997 return IntRange(SubRange->Width,
11998 SubRange->NonNegative || OutputTypeRange.NonNegative);
12001 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12004 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
12006 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
12007 InConstantContext, Approximate);
12012 Expr *TrueExpr = CO->getTrueExpr();
12014 return std::nullopt;
12016 std::optional<IntRange> L =
12019 return std::nullopt;
12021 Expr *FalseExpr = CO->getFalseExpr();
12023 return std::nullopt;
12025 std::optional<IntRange> R =
12028 return std::nullopt;
12030 return IntRange::join(*L, *R);
12033 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12034 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
12036 switch (BO->getOpcode()) {
12038 llvm_unreachable(
"builtin <=> should have class type");
12049 return IntRange::forBoolType();
12078 Combine = IntRange::bit_and;
12086 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
12087 if (I->getValue() == 1) {
12088 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
12089 return IntRange(R.Width,
true);
12099 case BO_ShrAssign: {
12101 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
12103 return std::nullopt;
12107 if (std::optional<llvm::APSInt> shift =
12108 BO->getRHS()->getIntegerConstantExpr(
C)) {
12109 if (shift->isNonNegative()) {
12110 if (shift->uge(L->Width))
12111 L->Width = (L->NonNegative ? 0 : 1);
12113 L->Width -= shift->getZExtValue();
12127 Combine = IntRange::sum;
12131 if (BO->getLHS()->getType()->isPointerType())
12134 Combine = IntRange::difference;
12139 Combine = IntRange::product;
12148 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
12150 return std::nullopt;
12153 if (std::optional<llvm::APSInt> divisor =
12154 BO->getRHS()->getIntegerConstantExpr(
C)) {
12155 unsigned log2 = divisor->logBase2();
12156 if (
log2 >= L->Width)
12157 L->Width = (L->NonNegative ? 0 : 1);
12159 L->Width = std::min(L->Width -
log2, MaxWidth);
12167 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
12169 return std::nullopt;
12171 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12175 Combine = IntRange::rem;
12187 unsigned opWidth =
C.getIntWidth(
T);
12189 InConstantContext, Approximate);
12191 return std::nullopt;
12194 InConstantContext, Approximate);
12196 return std::nullopt;
12198 IntRange
C = Combine(*L, *R);
12199 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
12200 C.Width = std::min(
C.Width, MaxWidth);
12204 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12205 switch (UO->getOpcode()) {
12208 return IntRange::forBoolType();
12222 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12225 return std::nullopt;
12230 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12240 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12243 return std::nullopt;
12248 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12258 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) {
12262 if (
const Expr *SourceExpr = OVE->getSourceExpr())
12268 return IntRange(BitField->getBitWidthValue(),
12269 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12272 return std::nullopt;
12278 bool InConstantContext,
12279 bool Approximate) {
12288 const llvm::fltSemantics &Src,
12289 const llvm::fltSemantics &Tgt) {
12290 llvm::APFloat truncated = value;
12293 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12294 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12296 return truncated.bitwiseIsEqual(value);
12305 const llvm::fltSemantics &Src,
12306 const llvm::fltSemantics &Tgt) {
12330 bool IsListInit =
false);
12345 return MacroName !=
"YES" && MacroName !=
"NO" &&
12346 MacroName !=
"true" && MacroName !=
"false";
12354 (!E->
getType()->isSignedIntegerType() ||
12369struct PromotedRange {
12371 llvm::APSInt PromotedMin;
12373 llvm::APSInt PromotedMax;
12375 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12377 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12378 else if (
R.Width >= BitWidth && !
Unsigned) {
12382 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12383 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12385 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12386 .extOrTrunc(BitWidth);
12387 PromotedMin.setIsUnsigned(
Unsigned);
12389 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12390 .extOrTrunc(BitWidth);
12391 PromotedMax.setIsUnsigned(
Unsigned);
12396 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12406 InRangeFlag = 0x40,
12409 Min =
LE | InRangeFlag,
12410 InRange = InRangeFlag,
12411 Max =
GE | InRangeFlag,
12414 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12419 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12420 Value.isUnsigned() == PromotedMin.isUnsigned());
12421 if (!isContiguous()) {
12422 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12423 if (
Value.isMinValue())
return Min;
12424 if (
Value.isMaxValue())
return Max;
12425 if (
Value >= PromotedMin)
return InRange;
12426 if (
Value <= PromotedMax)
return InRange;
12430 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12431 case -1:
return Less;
12432 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12434 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12435 case -1:
return InRange;
12436 case 0:
return Max;
12441 llvm_unreachable(
"impossible compare result");
12444 static std::optional<StringRef>
12446 if (Op == BO_Cmp) {
12448 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12450 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12451 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12452 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12453 return std::nullopt;
12460 }
else if (Op == BO_NE) {
12464 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12471 if (Op == BO_GE || Op == BO_LE)
12472 std::swap(TrueFlag, FalseFlag);
12475 return StringRef(
"true");
12477 return StringRef(
"false");
12478 return std::nullopt;
12485 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12486 if (ICE->getCastKind() != CK_IntegralCast &&
12487 ICE->getCastKind() != CK_NoOp)
12489 E = ICE->getSubExpr();
12498 enum ConstantValueKind {
12503 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12504 return BL->getValue() ? ConstantValueKind::LiteralTrue
12505 : ConstantValueKind::LiteralFalse;
12506 return ConstantValueKind::Miscellaneous;
12511 const llvm::APSInt &
Value,
12512 bool RhsConstant) {
12528 if (
Constant->getType()->isEnumeralType() &&
12534 if (!OtherValueRange)
12539 OtherT = AT->getValueType();
12540 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12544 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12550 bool OtherIsBooleanDespiteType =
12552 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12553 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12557 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12558 Value.isUnsigned());
12559 auto Cmp = OtherPromotedValueRange.compare(
Value);
12566 bool TautologicalTypeCompare =
false;
12568 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12569 Value.isUnsigned());
12570 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12573 TautologicalTypeCompare =
true;
12581 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12590 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12596 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12597 Other->getType()->isUnsignedIntegerOrEnumerationType())
12598 TautologicalTypeCompare =
true;
12603 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12604 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12608 llvm::raw_svector_ostream OS(PrettySourceValue);
12610 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12611 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12612 Constant->IgnoreParenImpCasts())) {
12613 OS << (BL->getValue() ?
"YES" :
"NO");
12618 if (!TautologicalTypeCompare) {
12620 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12626 if (IsObjCSignedCharBool) {
12628 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12629 << OS.str() << *
Result);
12636 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12640 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12641 : diag::warn_tautological_bool_compare)
12643 << OtherIsBooleanDespiteType << *
Result
12650 ? diag::warn_unsigned_enum_always_true_comparison
12651 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12652 : diag::warn_unsigned_always_true_comparison)
12653 : diag::warn_tautological_constant_compare;
12689 if (
T->isIntegralType(S.
Context)) {
12690 std::optional<llvm::APSInt> RHSValue =
12692 std::optional<llvm::APSInt> LHSValue =
12696 if (RHSValue && LHSValue)
12700 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12702 const bool RhsConstant = (
bool)RHSValue;
12703 Expr *Const = RhsConstant ? RHS : LHS;
12705 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12714 if (!
T->hasUnsignedIntegerRepresentation()) {
12728 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12730 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12736 Expr *signedOperand, *unsignedOperand;
12739 "unsigned comparison between two signed integer expressions?");
12740 signedOperand = LHS;
12741 unsignedOperand = RHS;
12743 signedOperand = RHS;
12744 unsignedOperand = LHS;
12750 std::optional<IntRange> signedRange =
12762 if (signedRange->NonNegative)
12774 if (!unsignedRange)
12779 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12781 if (unsignedRange->Width < comparisonWidth)
12786 S.
PDiag(diag::warn_mixed_sign_comparison)
12805 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12810 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12811 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12812 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12813 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12814 << BitfieldEnumDecl;
12821 Init->isValueDependent() ||
12822 Init->isTypeDependent())
12825 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12835 const PreferredTypeAttr *PTAttr =
nullptr;
12837 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12839 ED = PTAttr->getType()->getAsEnumDecl();
12847 bool SignedEnum = ED->getNumNegativeBits() > 0;
12854 unsigned DiagID = 0;
12855 if (SignedEnum && !SignedBitfield) {
12858 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12860 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12861 }
else if (SignedBitfield && !SignedEnum &&
12862 ED->getNumPositiveBits() == FieldWidth) {
12865 ? diag::warn_signed_bitfield_enum_conversion
12866 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12869 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12874 << SignedEnum << TypeRange;
12876 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12883 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12884 ED->getNumNegativeBits())
12885 : ED->getNumPositiveBits();
12888 if (BitsNeeded > FieldWidth) {
12892 ? diag::warn_bitfield_too_small_for_enum
12893 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12894 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12898 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12908 unsigned OriginalWidth =
Value.getBitWidth();
12914 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12915 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12922 if (!
Value.isSigned() ||
Value.isNegative())
12923 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12924 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12925 OriginalWidth =
Value.getSignificantBits();
12927 if (OriginalWidth <= FieldWidth)
12931 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12935 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12936 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12940 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12942 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12943 ? diag::warn_impcast_single_bit_bitield_precision_constant
12944 : diag::warn_impcast_bitfield_precision_constant)
12945 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12946 <<
Init->getSourceRange();
12983 bool PruneControlFlow =
false) {
12990 if (
T.hasAddressSpace())
12992 if (PruneControlFlow) {
13006 bool PruneControlFlow =
false) {
13013 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
13018 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
13019 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
13024 llvm::APFloat
Value(0.0);
13030 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
13035 diag::warn_impcast_float_integer, PruneWarnings);
13038 bool isExact =
false;
13041 T->hasUnsignedIntegerRepresentation());
13042 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
13043 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
13051 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
13052 precision = (precision * 59 + 195) / 196;
13053 Value.toString(PrettySourceValue, precision);
13057 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
13058 << PrettySourceValue);
13061 if (
Result == llvm::APFloat::opOK && isExact) {
13062 if (IsLiteral)
return;
13063 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
13069 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
13072 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
13073 : diag::warn_impcast_float_to_integer_out_of_range,
13076 unsigned DiagID = 0;
13079 DiagID = diag::warn_impcast_literal_float_to_integer;
13080 }
else if (IntegerValue == 0) {
13081 if (
Value.isZero()) {
13083 diag::warn_impcast_float_integer, PruneWarnings);
13086 DiagID = diag::warn_impcast_float_to_integer_zero;
13088 if (IntegerValue.isUnsigned()) {
13089 if (!IntegerValue.isMaxValue()) {
13091 diag::warn_impcast_float_integer, PruneWarnings);
13094 if (!IntegerValue.isMaxSignedValue() &&
13095 !IntegerValue.isMinSignedValue()) {
13097 diag::warn_impcast_float_integer, PruneWarnings);
13101 DiagID = diag::warn_impcast_float_to_integer;
13106 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
13108 IntegerValue.toString(PrettyTargetValue);
13110 if (PruneWarnings) {
13113 << E->
getType() <<
T.getUnqualifiedType()
13114 << PrettySourceValue << PrettyTargetValue
13118 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
13127 "Must be compound assignment operation");
13138 ->getComputationResultType()
13145 if (ResultBT->isInteger())
13147 E->
getExprLoc(), diag::warn_impcast_float_integer);
13149 if (!ResultBT->isFloatingPoint())
13158 diag::warn_impcast_float_result_precision);
13163 if (!Range.Width)
return "0";
13165 llvm::APSInt ValueInRange =
Value;
13166 ValueInRange.setIsSigned(!Range.NonNegative);
13167 ValueInRange = ValueInRange.trunc(Range.Width);
13168 return toString(ValueInRange, 10);
13178 const Type *Source =
13180 if (
Target->isDependentType())
13183 const auto *FloatCandidateBT =
13184 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13185 const Type *BoolCandidateType = ToBool ?
Target : Source;
13188 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13193 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13199 S, TheCall->
getArg(I - 1),
false));
13201 S, TheCall->
getArg(I + 1),
false));
13206 diag::warn_impcast_floating_point_to_bool);
13221 if (!IsGNUNullExpr && !HasNullPtrType)
13225 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
13226 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
13229 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13242 if (IsGNUNullExpr && Loc.
isMacroID()) {
13245 if (MacroName ==
"NULL")
13253 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13267 const char FirstLiteralCharacter =
13269 if (FirstLiteralCharacter ==
'0')
13275 if (CC.
isValid() &&
T->isCharType()) {
13276 const char FirstContextCharacter =
13278 if (FirstContextCharacter ==
'{')
13286 const auto *IL = dyn_cast<IntegerLiteral>(E);
13288 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13289 if (UO->getOpcode() == UO_Minus)
13290 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13301 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13305 if (Opc == BO_Shl) {
13308 if (LHS && LHS->getValue() == 0)
13309 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13311 RHS->getValue().isNonNegative() &&
13313 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13314 << (
Result.Val.getInt() != 0);
13316 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13323 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13328 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13329 (RHS->getValue() == 0 || RHS->getValue() == 1))
13332 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13333 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13341 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13347 if (Source->isChar16Type() &&
Target->isChar32Type())
13353 llvm::APSInt
Value(32);
13355 bool IsASCII =
Value <= 0x7F;
13356 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13357 bool ConversionPreservesSemantics =
13358 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13360 if (!ConversionPreservesSemantics) {
13361 auto IsSingleCodeUnitCP = [](
const QualType &
T,
13362 const llvm::APSInt &
Value) {
13363 if (
T->isChar8Type())
13364 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13365 if (
T->isChar16Type())
13366 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13367 assert(
T->isChar32Type());
13368 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13371 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13380 LosesPrecision ? diag::warn_impcast_unicode_precision
13381 : diag::warn_impcast_unicode_char_type);
13386 From =
Context.getCanonicalType(From);
13387 To =
Context.getCanonicalType(To);
13390 From = MaybePointee;
13397 if (FromFn->getCFIUncheckedCalleeAttr() &&
13398 !ToFn->getCFIUncheckedCalleeAttr())
13406 bool *ICContext,
bool IsListInit) {
13411 if (Source ==
Target)
return;
13412 if (
Target->isDependentType())
return;
13422 if (Source->isAtomicType())
13426 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13432 diag::warn_impcast_string_literal_to_bool);
13438 diag::warn_impcast_objective_c_literal_to_bool);
13440 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13452 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
13455 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13457 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13466 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13468 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13479 diag::err_impcast_incompatible_type);
13484 ? diag::err_impcast_complex_scalar
13485 : diag::warn_impcast_complex_scalar);
13494 if (
Target->isSveVLSBuiltinType() &&
13501 if (
Target->isRVVVLSBuiltinType() &&
13511 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
13519 diag::warn_hlsl_impcast_vector_truncation);
13531 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13532 Target = VecTy->getElementType().getTypePtr();
13536 if (
Target->isScalarType())
13537 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
13545 diag::warn_hlsl_impcast_matrix_truncation);
13551 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13552 Target = MatTy->getElementType().getTypePtr();
13554 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13560 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
13563 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13565 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13607 else if (Order < 0) {
13617 if (TargetBT && TargetBT->
isInteger()) {
13644 diag::warn_impcast_floating_point_to_bool);
13652 if (Source->isFixedPointType()) {
13653 if (
Target->isUnsaturatedFixedPointType()) {
13657 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13658 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
13659 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
13662 PDiag(diag::warn_impcast_fixed_point_range)
13663 <<
Value.toString() <<
T
13669 }
else if (
Target->isIntegerType()) {
13673 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13676 llvm::APSInt IntResult = FXResult.convertToInt(
13677 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
13682 PDiag(diag::warn_impcast_fixed_point_range)
13683 << FXResult.toString() <<
T
13690 }
else if (
Target->isUnsaturatedFixedPointType()) {
13691 if (Source->isIntegerType()) {
13698 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13703 PDiag(diag::warn_impcast_fixed_point_range)
13724 unsigned int SourcePrecision =
SourceRange->Width;
13728 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13731 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13732 SourcePrecision > TargetPrecision) {
13734 if (std::optional<llvm::APSInt> SourceInt =
13739 llvm::APFloat TargetFloatValue(
13741 llvm::APFloat::opStatus ConversionStatus =
13742 TargetFloatValue.convertFromAPInt(
13744 llvm::APFloat::rmNearestTiesToEven);
13746 if (ConversionStatus != llvm::APFloat::opOK) {
13748 SourceInt->toString(PrettySourceValue, 10);
13750 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13754 PDiag(diag::warn_impcast_integer_float_precision_constant)
13755 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13761 diag::warn_impcast_integer_float_precision);
13770 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13775 if (
Target->isBooleanType())
13779 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13783 if (!Source->isIntegerType() || !
Target->isIntegerType())
13788 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13791 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13794 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13799 if (!LikelySourceRange)
13802 IntRange SourceTypeRange =
13803 IntRange::forTargetOfCanonicalType(
Context, Source);
13804 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13806 if (LikelySourceRange->Width > TargetRange.Width) {
13810 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13811 if (TargetOBT->isWrapKind()) {
13818 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13819 if (SourceOBT->isWrapKind()) {
13829 llvm::APSInt
Value(32);
13839 PDiag(diag::warn_impcast_integer_precision_constant)
13840 << PrettySourceValue << PrettyTargetValue
13850 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13851 if (UO->getOpcode() == UO_Minus)
13853 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13856 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13860 diag::warn_impcast_integer_precision);
13863 if (TargetRange.Width > SourceTypeRange.Width) {
13864 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13865 if (UO->getOpcode() == UO_Minus)
13866 if (Source->isUnsignedIntegerType()) {
13867 if (
Target->isUnsignedIntegerType())
13869 diag::warn_impcast_high_order_zero_bits);
13870 if (
Target->isSignedIntegerType())
13872 diag::warn_impcast_nonnegative_result);
13876 if (TargetRange.Width == LikelySourceRange->Width &&
13877 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13878 Source->isSignedIntegerType()) {
13892 PDiag(diag::warn_impcast_integer_precision_constant)
13893 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13903 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13904 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13905 LikelySourceRange->Width == TargetRange.Width))) {
13909 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13911 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13915 unsigned DiagID = diag::warn_impcast_integer_sign;
13923 DiagID = diag::warn_impcast_integer_sign_conditional;
13940 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13942 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13943 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13944 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13945 TargetEnum->getDecl()->hasNameForLinkage() &&
13946 SourceEnum != TargetEnum) {
13951 diag::warn_impcast_different_enum_types);
13965 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13978 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13979 TrueExpr = BCO->getCommon();
13981 bool Suspicious =
false;
13985 if (
T->isBooleanType())
13990 if (!Suspicious)
return;
13993 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
14000 Suspicious =
false;
14005 E->
getType(), CC, &Suspicious);
14022struct AnalyzeImplicitConversionsWorkItem {
14031 bool ExtraCheckForImplicitConversion,
14034 WorkList.push_back({E, CC,
false});
14036 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
14043 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
14045 Expr *OrigE = Item.E;
14064 Expr *SourceExpr = E;
14069 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
14070 if (
auto *Src = OVE->getSourceExpr())
14073 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
14074 if (UO->getOpcode() == UO_Not &&
14075 UO->getSubExpr()->isKnownToHaveBooleanValue())
14076 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
14080 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
14081 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
14082 BO->getLHS()->isKnownToHaveBooleanValue() &&
14083 BO->getRHS()->isKnownToHaveBooleanValue() &&
14084 BO->getLHS()->HasSideEffects(S.
Context) &&
14085 BO->getRHS()->HasSideEffects(S.
Context)) {
14096 if (SR.str() ==
"&" || SR.str() ==
"|") {
14098 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
14099 << (BO->getOpcode() == BO_And ?
"&" :
"|")
14102 BO->getOperatorLoc(),
14103 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
14104 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
14106 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
14124 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
14130 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
14145 for (
auto *SE : POE->semantics())
14146 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
14147 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
14151 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
14152 E = CE->getSubExpr();
14158 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
14159 if (InitListE->getNumInits() == 1) {
14160 E = InitListE->getInit(0);
14167 WorkList.push_back({E, CC, IsListInit});
14171 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
14172 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
14176 if (OutArgE->isInOut())
14177 WorkList.push_back(
14178 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14179 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14185 if (BO->isComparisonOp())
14189 if (BO->getOpcode() == BO_Assign)
14192 if (BO->isAssignmentOp())
14208 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14210 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14214 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14215 if (ChildExpr == CSE->getOperand())
14221 if (IsLogicalAndOperator &&
14226 WorkList.push_back({ChildExpr, CC, IsListInit});
14240 if (
U->getOpcode() == UO_LNot) {
14242 }
else if (
U->getOpcode() != UO_AddrOf) {
14243 if (
U->getSubExpr()->getType()->isAtomicType())
14244 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14245 diag::warn_atomic_implicit_seq_cst);
14256 WorkList.push_back({OrigE, CC, IsListInit});
14257 while (!WorkList.empty())
14269 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14272 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14273 if (!M->getMemberDecl()->getType()->isReferenceType())
14275 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14276 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14278 FD =
Call->getDirectCallee();
14287 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14327 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14328 : diag::warn_this_bool_conversion;
14333 bool IsAddressOf =
false;
14335 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14336 if (UO->getOpcode() != UO_AddrOf)
14338 IsAddressOf =
true;
14339 E = UO->getSubExpr();
14343 unsigned DiagID = IsCompare
14344 ? diag::warn_address_of_reference_null_compare
14345 : diag::warn_address_of_reference_bool_conversion;
14353 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14356 llvm::raw_string_ostream S(Str);
14358 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14359 : diag::warn_cast_nonnull_to_bool;
14362 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14367 if (
auto *Callee =
Call->getDirectCallee()) {
14368 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14369 ComplainAboutNonnullParamOrCall(A);
14378 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14379 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14380 MRecordDecl && MRecordDecl->isLambda()) {
14383 << MRecordDecl->getSourceRange() << Range << IsEqual;
14393 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14394 D = M->getMemberDecl();
14402 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14405 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14406 ComplainAboutNonnullParamOrCall(A);
14410 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14414 auto ParamIter = llvm::find(FD->
parameters(), PV);
14416 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14420 ComplainAboutNonnullParamOrCall(
NonNull);
14425 if (ArgNo.getASTIndex() == ParamNo) {
14426 ComplainAboutNonnullParamOrCall(
NonNull);
14437 const bool IsFunctionReference =
14438 T->isReferenceType() &&
T->getPointeeType()->isFunctionType();
14439 if (IsFunctionReference)
14440 T =
T->getPointeeType();
14441 const bool IsArray =
T->isArrayType();
14442 const bool IsFunction =
T->isFunctionType();
14445 if (IsAddressOf && IsFunction) {
14450 if (!IsAddressOf && !IsFunction && !IsArray)
14455 llvm::raw_string_ostream S(Str);
14458 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14459 : diag::warn_impcast_pointer_to_bool;
14466 DiagType = AddressOf;
14467 else if (IsFunction)
14468 DiagType = FunctionPointer;
14470 DiagType = ArrayPointer;
14472 llvm_unreachable(
"Could not determine diagnostic.");
14474 << Range << IsEqual;
14477 if (!IsFunction || IsFunctionReference)
14488 if (ReturnType.
isNull())
14519 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14520 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14522 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14523 Target->isUnsignedIntegerType()) {
14527 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14528 : diag::warn_impcast_overflow_behavior_pedantic;
14532 ? diag::warn_impcast_overflow_behavior_assignment
14533 : diag::warn_impcast_overflow_behavior;
14539 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14540 if (TargetOBT->isWrapKind()) {
14560 CheckArrayAccess(E);
14570void Sema::CheckForIntOverflow (
const Expr *E) {
14572 SmallVector<const Expr *, 2> Exprs(1, E);
14575 const Expr *OriginalE = Exprs.pop_back_val();
14584 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14585 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14588 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14589 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14590 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14592 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14593 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14594 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14595 Exprs.push_back(Temporary->getSubExpr());
14596 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14597 Exprs.push_back(
Array->getIdx());
14598 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14599 Exprs.push_back(Compound->getInitializer());
14600 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14601 New &&
New->isArray()) {
14602 if (
auto ArraySize =
New->getArraySize())
14603 Exprs.push_back(*ArraySize);
14604 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14605 Exprs.push_back(MTE->getSubExpr());
14606 }
while (!Exprs.empty());
14614 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14621 class SequenceTree {
14623 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14624 unsigned Parent : 31;
14625 LLVM_PREFERRED_TYPE(
bool)
14626 unsigned Merged : 1;
14628 SmallVector<Value, 8> Values;
14634 friend class SequenceTree;
14638 explicit Seq(
unsigned N) : Index(N) {}
14641 Seq() : Index(0) {}
14644 SequenceTree() { Values.push_back(
Value(0)); }
14645 Seq root()
const {
return Seq(0); }
14650 Seq allocate(
Seq Parent) {
14651 Values.push_back(
Value(Parent.Index));
14652 return Seq(Values.size() - 1);
14657 Values[S.Index].Merged =
true;
14663 bool isUnsequenced(
Seq Cur,
Seq Old) {
14664 unsigned C = representative(Cur.Index);
14665 unsigned Target = representative(Old.Index);
14669 C = Values[
C].Parent;
14676 unsigned representative(
unsigned K) {
14677 if (Values[K].Merged)
14679 return Values[K].Parent = representative(Values[K].Parent);
14685 using Object =
const NamedDecl *;
14699 UK_ModAsSideEffect,
14701 UK_Count = UK_ModAsSideEffect + 1
14707 const Expr *UsageExpr =
nullptr;
14708 SequenceTree::Seq
Seq;
14714 Usage Uses[UK_Count];
14717 bool Diagnosed =
false;
14721 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14729 UsageInfoMap UsageMap;
14732 SequenceTree::Seq Region;
14736 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14740 SmallVectorImpl<const Expr *> &WorkList;
14747 struct SequencedSubexpression {
14748 SequencedSubexpression(SequenceChecker &
Self)
14749 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14750 Self.ModAsSideEffect = &ModAsSideEffect;
14753 ~SequencedSubexpression() {
14754 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14758 UsageInfo &UI =
Self.UsageMap[M.first];
14759 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14760 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14761 SideEffectUsage = M.second;
14763 Self.ModAsSideEffect = OldModAsSideEffect;
14766 SequenceChecker &
Self;
14767 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14768 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14775 class EvaluationTracker {
14777 EvaluationTracker(SequenceChecker &
Self)
14779 Self.EvalTracker =
this;
14782 ~EvaluationTracker() {
14783 Self.EvalTracker = Prev;
14785 Prev->EvalOK &= EvalOK;
14788 bool evaluate(
const Expr *E,
bool &
Result) {
14793 Self.SemaRef.isConstantEvaluatedContext());
14798 SequenceChecker &
Self;
14799 EvaluationTracker *Prev;
14800 bool EvalOK =
true;
14801 } *EvalTracker =
nullptr;
14805 Object getObject(
const Expr *E,
bool Mod)
const {
14807 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14808 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14809 return getObject(UO->getSubExpr(), Mod);
14810 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14811 if (BO->getOpcode() == BO_Comma)
14812 return getObject(BO->getRHS(), Mod);
14813 if (Mod && BO->isAssignmentOp())
14814 return getObject(BO->getLHS(), Mod);
14815 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14818 return ME->getMemberDecl();
14819 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14828 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14830 Usage &U = UI.Uses[UK];
14831 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14835 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14836 ModAsSideEffect->push_back(std::make_pair(O, U));
14838 U.UsageExpr = UsageExpr;
14848 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14849 UsageKind OtherKind,
bool IsModMod) {
14853 const Usage &U = UI.Uses[OtherKind];
14854 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14857 const Expr *Mod = U.UsageExpr;
14858 const Expr *ModOrUse = UsageExpr;
14859 if (OtherKind == UK_Use)
14860 std::swap(Mod, ModOrUse);
14864 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14865 : diag::warn_unsequenced_mod_use)
14866 << O << SourceRange(ModOrUse->
getExprLoc()));
14867 UI.Diagnosed =
true;
14896 void notePreUse(
Object O,
const Expr *UseExpr) {
14897 UsageInfo &UI = UsageMap[O];
14899 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14902 void notePostUse(
Object O,
const Expr *UseExpr) {
14903 UsageInfo &UI = UsageMap[O];
14904 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14906 addUsage(O, UI, UseExpr, UK_Use);
14909 void notePreMod(
Object O,
const Expr *ModExpr) {
14910 UsageInfo &UI = UsageMap[O];
14912 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14913 checkUsage(O, UI, ModExpr, UK_Use,
false);
14916 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14917 UsageInfo &UI = UsageMap[O];
14918 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14920 addUsage(O, UI, ModExpr, UK);
14924 SequenceChecker(Sema &S,
const Expr *E,
14925 SmallVectorImpl<const Expr *> &WorkList)
14926 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14930 (void)this->WorkList;
14933 void VisitStmt(
const Stmt *S) {
14937 void VisitExpr(
const Expr *E) {
14939 Base::VisitStmt(E);
14942 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14943 for (
auto *Sub : CSE->
children()) {
14944 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14959 void VisitCastExpr(
const CastExpr *E) {
14971 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14972 const Expr *SequencedAfter) {
14973 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14974 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14975 SequenceTree::Seq OldRegion = Region;
14978 SequencedSubexpression SeqBefore(*
this);
14979 Region = BeforeRegion;
14980 Visit(SequencedBefore);
14983 Region = AfterRegion;
14984 Visit(SequencedAfter);
14986 Region = OldRegion;
14988 Tree.merge(BeforeRegion);
14989 Tree.merge(AfterRegion);
14992 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14997 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
15004 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15005 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15006 void VisitBinPtrMem(
const BinaryOperator *BO) {
15011 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15018 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15019 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15020 void VisitBinShlShr(
const BinaryOperator *BO) {
15024 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15031 void VisitBinComma(
const BinaryOperator *BO) {
15036 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15039 void VisitBinAssign(
const BinaryOperator *BO) {
15040 SequenceTree::Seq RHSRegion;
15041 SequenceTree::Seq LHSRegion;
15043 RHSRegion = Tree.allocate(Region);
15044 LHSRegion = Tree.allocate(Region);
15046 RHSRegion = Region;
15047 LHSRegion = Region;
15049 SequenceTree::Seq OldRegion = Region;
15065 SequencedSubexpression SeqBefore(*
this);
15066 Region = RHSRegion;
15070 Region = LHSRegion;
15074 notePostUse(O, BO);
15078 Region = LHSRegion;
15082 notePostUse(O, BO);
15084 Region = RHSRegion;
15092 Region = OldRegion;
15096 : UK_ModAsSideEffect);
15098 Tree.merge(RHSRegion);
15099 Tree.merge(LHSRegion);
15103 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
15104 VisitBinAssign(CAO);
15107 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15108 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15109 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
15112 return VisitExpr(UO);
15120 : UK_ModAsSideEffect);
15123 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15124 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15125 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
15128 return VisitExpr(UO);
15132 notePostMod(O, UO, UK_ModAsSideEffect);
15135 void VisitBinLOr(
const BinaryOperator *BO) {
15141 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15142 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15143 SequenceTree::Seq OldRegion = Region;
15145 EvaluationTracker Eval(*
this);
15147 SequencedSubexpression Sequenced(*
this);
15148 Region = LHSRegion;
15155 bool EvalResult =
false;
15156 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15157 bool ShouldVisitRHS = !EvalOK || !EvalResult;
15158 if (ShouldVisitRHS) {
15159 Region = RHSRegion;
15163 Region = OldRegion;
15164 Tree.merge(LHSRegion);
15165 Tree.merge(RHSRegion);
15168 void VisitBinLAnd(
const BinaryOperator *BO) {
15174 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15175 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15176 SequenceTree::Seq OldRegion = Region;
15178 EvaluationTracker Eval(*
this);
15180 SequencedSubexpression Sequenced(*
this);
15181 Region = LHSRegion;
15187 bool EvalResult =
false;
15188 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15189 bool ShouldVisitRHS = !EvalOK || EvalResult;
15190 if (ShouldVisitRHS) {
15191 Region = RHSRegion;
15195 Region = OldRegion;
15196 Tree.merge(LHSRegion);
15197 Tree.merge(RHSRegion);
15200 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15205 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15221 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15222 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15223 SequenceTree::Seq OldRegion = Region;
15225 EvaluationTracker Eval(*
this);
15227 SequencedSubexpression Sequenced(*
this);
15228 Region = ConditionRegion;
15238 bool EvalResult =
false;
15239 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15240 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15241 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15242 if (ShouldVisitTrueExpr) {
15243 Region = TrueRegion;
15246 if (ShouldVisitFalseExpr) {
15247 Region = FalseRegion;
15251 Region = OldRegion;
15252 Tree.merge(ConditionRegion);
15253 Tree.merge(TrueRegion);
15254 Tree.merge(FalseRegion);
15257 void VisitCallExpr(
const CallExpr *CE) {
15269 SequencedSubexpression Sequenced(*
this);
15274 SequenceTree::Seq CalleeRegion;
15275 SequenceTree::Seq OtherRegion;
15276 if (SemaRef.getLangOpts().CPlusPlus17) {
15277 CalleeRegion = Tree.allocate(Region);
15278 OtherRegion = Tree.allocate(Region);
15280 CalleeRegion = Region;
15281 OtherRegion = Region;
15283 SequenceTree::Seq OldRegion = Region;
15286 Region = CalleeRegion;
15288 SequencedSubexpression Sequenced(*this);
15289 Visit(CE->getCallee());
15291 Visit(CE->getCallee());
15295 Region = OtherRegion;
15299 Region = OldRegion;
15301 Tree.merge(CalleeRegion);
15302 Tree.merge(OtherRegion);
15320 return VisitCallExpr(CXXOCE);
15331 case OO_MinusEqual:
15333 case OO_SlashEqual:
15334 case OO_PercentEqual:
15335 case OO_CaretEqual:
15338 case OO_LessLessEqual:
15339 case OO_GreaterGreaterEqual:
15340 SequencingKind = RHSBeforeLHS;
15344 case OO_GreaterGreater:
15350 SequencingKind = LHSBeforeRHS;
15354 SequencingKind = LHSBeforeRest;
15358 SequencingKind = NoSequencing;
15362 if (SequencingKind == NoSequencing)
15363 return VisitCallExpr(CXXOCE);
15366 SequencedSubexpression Sequenced(*
this);
15369 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15370 "Should only get there with C++17 and above!");
15371 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15372 "Should only get there with an overloaded binary operator"
15373 " or an overloaded call operator!");
15375 if (SequencingKind == LHSBeforeRest) {
15376 assert(CXXOCE->getOperator() == OO_Call &&
15377 "We should only have an overloaded call operator here!");
15386 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15387 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15388 SequenceTree::Seq OldRegion = Region;
15390 assert(CXXOCE->getNumArgs() >= 1 &&
15391 "An overloaded call operator must have at least one argument"
15392 " for the postfix-expression!");
15393 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15394 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15395 CXXOCE->getNumArgs() - 1);
15399 Region = PostfixExprRegion;
15400 SequencedSubexpression Sequenced(*this);
15401 Visit(PostfixExpr);
15405 Region = ArgsRegion;
15406 for (const Expr *Arg : Args)
15409 Region = OldRegion;
15410 Tree.merge(PostfixExprRegion);
15411 Tree.merge(ArgsRegion);
15413 assert(CXXOCE->getNumArgs() == 2 &&
15414 "Should only have two arguments here!");
15415 assert((SequencingKind == LHSBeforeRHS ||
15416 SequencingKind == RHSBeforeLHS) &&
15417 "Unexpected sequencing kind!");
15421 const Expr *E1 = CXXOCE->getArg(0);
15422 const Expr *E2 = CXXOCE->getArg(1);
15423 if (SequencingKind == RHSBeforeLHS)
15426 return VisitSequencedExpressions(E1, E2);
15433 SequencedSubexpression Sequenced(*
this);
15436 return VisitExpr(CCE);
15439 SequenceExpressionsInOrder(
15445 return VisitExpr(ILE);
15448 SequenceExpressionsInOrder(ILE->
inits());
15460 SequenceTree::Seq Parent = Region;
15461 for (
const Expr *E : ExpressionList) {
15464 Region = Tree.allocate(Parent);
15465 Elts.push_back(Region);
15471 for (
unsigned I = 0; I < Elts.size(); ++I)
15472 Tree.merge(Elts[I]);
15476SequenceChecker::UsageInfo::UsageInfo() =
default;
15480void Sema::CheckUnsequencedOperations(
const Expr *E) {
15481 SmallVector<const Expr *, 8> WorkList;
15482 WorkList.push_back(E);
15483 while (!WorkList.empty()) {
15484 const Expr *Item = WorkList.pop_back_val();
15485 SequenceChecker(*
this, Item, WorkList);
15490 bool IsConstexpr) {
15493 CheckImplicitConversions(E, CheckLoc);
15495 CheckUnsequencedOperations(E);
15497 CheckForIntOverflow(E);
15510 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15514 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15518 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15532 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15536 bool CheckParameterNames) {
15537 bool HasInvalidParm =
false;
15539 assert(Param &&
"null in a parameter list");
15548 if (!Param->isInvalidDecl() &&
15550 diag::err_typecheck_decl_incomplete_type) ||
15552 diag::err_abstract_type_in_decl,
15554 Param->setInvalidDecl();
15555 HasInvalidParm =
true;
15560 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15564 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15572 QualType PType = Param->getOriginalType();
15580 if (!Param->isInvalidDecl()) {
15581 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15582 if (!ClassDecl->isInvalidDecl() &&
15583 !ClassDecl->hasIrrelevantDestructor() &&
15584 !ClassDecl->isDependentContext() &&
15585 ClassDecl->isParamDestroyedInCallee()) {
15597 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15598 if (!Param->getType().isConstQualified())
15599 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15603 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15608 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15609 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15614 if (!Param->isInvalidDecl() &&
15615 Param->getOriginalType()->isWebAssemblyTableType()) {
15616 Param->setInvalidDecl();
15617 HasInvalidParm =
true;
15618 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15622 return HasInvalidParm;
15625std::optional<std::pair<
15634static std::pair<CharUnits, CharUnits>
15642 if (
Base->isVirtual()) {
15649 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15656 DerivedType =
Base->getType();
15659 return std::make_pair(BaseAlignment, Offset);
15663static std::optional<std::pair<CharUnits, CharUnits>>
15669 return std::nullopt;
15674 return std::nullopt;
15678 CharUnits Offset = EltSize * IdxRes->getExtValue();
15681 return std::make_pair(P->first, P->second + Offset);
15687 return std::make_pair(
15688 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15694std::optional<std::pair<
15702 case Stmt::CStyleCastExprClass:
15703 case Stmt::CXXStaticCastExprClass:
15704 case Stmt::ImplicitCastExprClass: {
15706 const Expr *From = CE->getSubExpr();
15707 switch (CE->getCastKind()) {
15712 case CK_UncheckedDerivedToBase:
15713 case CK_DerivedToBase: {
15723 case Stmt::ArraySubscriptExprClass: {
15728 case Stmt::DeclRefExprClass: {
15732 if (!VD->getType()->isReferenceType()) {
15734 if (VD->hasDependentAlignment())
15743 case Stmt::MemberExprClass: {
15745 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15749 std::optional<std::pair<CharUnits, CharUnits>> P;
15758 return std::make_pair(P->first,
15761 case Stmt::UnaryOperatorClass: {
15771 case Stmt::BinaryOperatorClass: {
15783 return std::nullopt;
15788std::optional<std::pair<
15797 case Stmt::CStyleCastExprClass:
15798 case Stmt::CXXStaticCastExprClass:
15799 case Stmt::ImplicitCastExprClass: {
15801 const Expr *From = CE->getSubExpr();
15802 switch (CE->getCastKind()) {
15807 case CK_ArrayToPointerDecay:
15809 case CK_UncheckedDerivedToBase:
15810 case CK_DerivedToBase: {
15820 case Stmt::CXXThisExprClass: {
15825 case Stmt::UnaryOperatorClass: {
15831 case Stmt::BinaryOperatorClass: {
15840 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15841 std::swap(LHS, RHS);
15851 return std::nullopt;
15856 std::optional<std::pair<CharUnits, CharUnits>> P =
15860 return P->first.alignmentAtOffset(P->second);
15878 if (!DestPtr)
return;
15884 if (DestAlign.
isOne())
return;
15888 if (!SrcPtr)
return;
15899 if (SrcAlign >= DestAlign)
return;
15904 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15908void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15910 bool AllowOnePastEnd,
bool IndexNegated) {
15919 const Type *EffectiveType =
15923 Context.getAsConstantArrayType(BaseExpr->
getType());
15926 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15928 const Type *BaseType =
15930 bool IsUnboundedArray =
15932 Context, StrictFlexArraysLevel,
15935 (!IsUnboundedArray && BaseType->isDependentType()))
15943 if (IndexNegated) {
15944 index.setIsUnsigned(
false);
15948 if (IsUnboundedArray) {
15951 if (
index.isUnsigned() || !
index.isNegative()) {
15953 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15955 if (
index.getBitWidth() < AddrBits)
15957 std::optional<CharUnits> ElemCharUnits =
15958 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15961 if (!ElemCharUnits || ElemCharUnits->isZero())
15963 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15968 if (
index.getActiveBits() <= AddrBits) {
15970 llvm::APInt Product(
index);
15972 Product = Product.umul_ov(ElemBytes, Overflow);
15973 if (!Overflow && Product.getActiveBits() <= AddrBits)
15979 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15980 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15982 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15983 MaxElems = MaxElems.udiv(ElemBytes);
15986 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15987 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15992 PDiag(DiagID) << index << AddrBits
15993 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15994 << ElemBytes << MaxElems
15995 << MaxElems.getZExtValue()
15998 const NamedDecl *ND =
nullptr;
16000 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16002 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16004 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16005 ND = ME->getMemberDecl();
16009 PDiag(diag::note_array_declared_here) << ND);
16014 if (index.isUnsigned() || !index.isNegative()) {
16024 llvm::APInt size = ArrayTy->
getSize();
16026 if (BaseType != EffectiveType) {
16034 if (!ptrarith_typesize)
16035 ptrarith_typesize =
Context.getCharWidth();
16037 if (ptrarith_typesize != array_typesize) {
16039 uint64_t ratio = array_typesize / ptrarith_typesize;
16043 if (ptrarith_typesize * ratio == array_typesize)
16044 size *= llvm::APInt(size.getBitWidth(), ratio);
16048 if (size.getBitWidth() > index.getBitWidth())
16049 index = index.zext(size.getBitWidth());
16050 else if (size.getBitWidth() < index.getBitWidth())
16051 size = size.zext(index.getBitWidth());
16057 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
16064 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
16066 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
16067 SourceLocation IndexLoc =
16069 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
16074 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
16075 : diag::warn_ptr_arith_exceeds_bounds;
16076 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
16077 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
16081 << index << ArrayTy->
desugar() << CastMsg
16084 unsigned DiagID = diag::warn_array_index_precedes_bounds;
16086 DiagID = diag::warn_ptr_arith_precedes_bounds;
16087 if (index.isNegative()) index = -index;
16094 const NamedDecl *ND =
nullptr;
16096 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16098 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16100 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16101 ND = ME->getMemberDecl();
16105 PDiag(diag::note_array_declared_here) << ND);
16108void Sema::CheckArrayAccess(
const Expr *
expr) {
16109 int AllowOnePastEnd = 0;
16111 expr =
expr->IgnoreParenImpCasts();
16112 switch (
expr->getStmtClass()) {
16113 case Stmt::ArraySubscriptExprClass: {
16116 AllowOnePastEnd > 0);
16120 case Stmt::MemberExprClass: {
16124 case Stmt::CXXMemberCallExprClass: {
16128 case Stmt::ArraySectionExprClass: {
16134 nullptr, AllowOnePastEnd > 0);
16137 case Stmt::UnaryOperatorClass: {
16153 case Stmt::ConditionalOperatorClass: {
16155 if (
const Expr *lhs = cond->
getLHS())
16156 CheckArrayAccess(lhs);
16157 if (
const Expr *rhs = cond->
getRHS())
16158 CheckArrayAccess(rhs);
16161 case Stmt::CXXOperatorCallExprClass: {
16163 for (
const auto *Arg : OCE->arguments())
16164 CheckArrayAccess(Arg);
16174 Expr *RHS,
bool isProperty) {
16186 S.
Diag(Loc, diag::warn_arc_literal_assign)
16188 << (isProperty ? 0 : 1)
16196 Expr *RHS,
bool isProperty) {
16199 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16200 S.
Diag(Loc, diag::warn_arc_retained_assign)
16202 << (isProperty ? 0 : 1)
16206 RHS =
cast->getSubExpr();
16248 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16277 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16278 Diag(Loc, diag::warn_arc_retained_property_assign)
16282 RHS =
cast->getSubExpr();
16305 bool StmtLineInvalid;
16306 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16308 if (StmtLineInvalid)
16311 bool BodyLineInvalid;
16312 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16314 if (BodyLineInvalid)
16318 if (StmtLine != BodyLine)
16333 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16342 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16346 const Stmt *PossibleBody) {
16352 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16353 StmtLoc = FS->getRParenLoc();
16354 Body = FS->getBody();
16355 DiagID = diag::warn_empty_for_body;
16356 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16357 StmtLoc = WS->getRParenLoc();
16358 Body = WS->getBody();
16359 DiagID = diag::warn_empty_while_body;
16364 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16388 if (!ProbableTypo) {
16389 bool BodyColInvalid;
16390 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16392 if (BodyColInvalid)
16395 bool StmtColInvalid;
16398 if (StmtColInvalid)
16401 if (BodyCol > StmtCol)
16402 ProbableTypo =
true;
16405 if (ProbableTypo) {
16407 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16415 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16427 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16429 RHSExpr = CE->
getArg(0);
16430 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16431 CXXSCE && CXXSCE->isXValue())
16432 RHSExpr = CXXSCE->getSubExpr();
16436 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16437 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16440 if (LHSDeclRef && RHSDeclRef) {
16447 auto D =
Diag(OpLoc, diag::warn_self_move)
16463 const Expr *LHSBase = LHSExpr;
16464 const Expr *RHSBase = RHSExpr;
16465 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16466 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16467 if (!LHSME || !RHSME)
16470 while (LHSME && RHSME) {
16477 LHSME = dyn_cast<MemberExpr>(LHSBase);
16478 RHSME = dyn_cast<MemberExpr>(RHSBase);
16481 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16482 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16483 if (LHSDeclRef && RHSDeclRef) {
16490 Diag(OpLoc, diag::warn_self_move)
16497 Diag(OpLoc, diag::warn_self_move)
16521 bool AreUnionMembers =
false) {
16525 assert(((Field1Parent->isStructureOrClassType() &&
16526 Field2Parent->isStructureOrClassType()) ||
16527 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16528 "Can't evaluate layout compatibility between a struct field and a "
16530 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16531 (AreUnionMembers && Field1Parent->isUnionType())) &&
16532 "AreUnionMembers should be 'true' for union fields (only).");
16546 if (Bits1 != Bits2)
16550 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16551 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16554 if (!AreUnionMembers &&
16566 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16567 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16569 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16570 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16575 return isLayoutCompatible(C, F1, F2);
16586 for (
auto *Field1 : RD1->
fields()) {
16587 auto I = UnmatchedFields.begin();
16588 auto E = UnmatchedFields.end();
16590 for ( ; I != E; ++I) {
16592 bool Result = UnmatchedFields.erase(*I);
16602 return UnmatchedFields.empty();
16628 if (
C.hasSameType(T1, T2))
16637 if (TC1 == Type::Enum)
16639 if (TC1 == Type::Record) {
16658 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16689 const ValueDecl **VD, uint64_t *MagicValue,
16690 bool isConstantEvaluated) {
16698 case Stmt::UnaryOperatorClass: {
16707 case Stmt::DeclRefExprClass: {
16713 case Stmt::IntegerLiteralClass: {
16715 llvm::APInt MagicValueAPInt = IL->
getValue();
16716 if (MagicValueAPInt.getActiveBits() <= 64) {
16717 *MagicValue = MagicValueAPInt.getZExtValue();
16723 case Stmt::BinaryConditionalOperatorClass:
16724 case Stmt::ConditionalOperatorClass: {
16729 isConstantEvaluated)) {
16739 case Stmt::BinaryOperatorClass: {
16742 TypeExpr = BO->
getRHS();
16772 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16775 bool isConstantEvaluated) {
16776 FoundWrongKind =
false;
16781 uint64_t MagicValue;
16783 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16787 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16788 if (I->getArgumentKind() != ArgumentKind) {
16789 FoundWrongKind =
true;
16792 TypeInfo.Type = I->getMatchingCType();
16793 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16794 TypeInfo.MustBeNull = I->getMustBeNull();
16805 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16806 if (I == MagicValues->end())
16815 bool LayoutCompatible,
16817 if (!TypeTagForDatatypeMagicValues)
16818 TypeTagForDatatypeMagicValues.reset(
16819 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16822 (*TypeTagForDatatypeMagicValues)[Magic] =
16838 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16839 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16840 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16841 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16844void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16847 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16848 bool IsPointerAttr = Attr->getIsPointer();
16851 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16852 if (TypeTagIdxAST >= ExprArgs.size()) {
16853 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16854 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16857 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16858 bool FoundWrongKind;
16861 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16863 if (FoundWrongKind)
16865 diag::warn_type_tag_for_datatype_wrong_kind)
16871 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16872 if (ArgumentIdxAST >= ExprArgs.size()) {
16873 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16874 << 1 << Attr->getArgumentIdx().getSourceIndex();
16877 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16878 if (IsPointerAttr) {
16880 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16881 if (ICE->getType()->isVoidPointerType() &&
16882 ICE->getCastKind() == CK_BitCast)
16883 ArgumentExpr = ICE->getSubExpr();
16885 QualType ArgumentType = ArgumentExpr->
getType();
16891 if (TypeInfo.MustBeNull) {
16896 diag::warn_type_safety_null_pointer_required)
16904 QualType RequiredType = TypeInfo.Type;
16906 RequiredType =
Context.getPointerType(RequiredType);
16908 bool mismatch =
false;
16909 if (!TypeInfo.LayoutCompatible) {
16910 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16931 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16932 << ArgumentType << ArgumentKind
16933 << TypeInfo.LayoutCompatible << RequiredType
16951 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16959 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
16965 auto &MisalignedMembersForExpr =
16967 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16968 if (MA != MisalignedMembersForExpr.end() &&
16969 (
T->isDependentType() ||
T->isIntegerType() ||
16970 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
16972 T->getPointeeType()) <= MA->Alignment))))
16973 MisalignedMembersForExpr.erase(MA);
16982 const auto *ME = dyn_cast<MemberExpr>(E);
16994 bool AnyIsPacked =
false;
16996 QualType BaseType = ME->getBase()->getType();
16997 if (BaseType->isDependentType())
17001 auto *RD = BaseType->castAsRecordDecl();
17006 auto *FD = dyn_cast<FieldDecl>(MD);
17012 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
17013 ReverseMemberChain.push_back(FD);
17016 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
17018 assert(TopME &&
"We did not compute a topmost MemberExpr!");
17025 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
17036 if (ExpectedAlignment.
isOne())
17041 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
17042 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
17046 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
17050 if (DRE && !TopME->
isArrow()) {
17053 CompleteObjectAlignment =
17054 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
17058 if (!Offset.isMultipleOf(ExpectedAlignment) ||
17061 CompleteObjectAlignment < ExpectedAlignment) {
17072 for (
FieldDecl *FDI : ReverseMemberChain) {
17073 if (FDI->hasAttr<PackedAttr>() ||
17074 FDI->getParent()->hasAttr<PackedAttr>()) {
17076 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
17082 assert(FD &&
"We did not find a packed FieldDecl!");
17083 Action(E, FD->
getParent(), FD, Alignment);
17087void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
17088 using namespace std::placeholders;
17091 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
17115bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
17116 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
17143 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
17160 assert(!Args.empty() &&
"Should have at least one argument.");
17162 Expr *Arg0 = Args.front();
17165 auto EmitError = [&](
Expr *ArgI) {
17167 diag::err_typecheck_call_different_arg_types)
17168 << Arg0->
getType() << ArgI->getType();
17173 for (
Expr *ArgI : Args.drop_front())
17184 for (
Expr *ArgI : Args.drop_front()) {
17185 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17188 VecI->getElementType()) ||
17189 Vec0->getNumElements() != VecI->getNumElements()) {
17198std::optional<QualType>
17202 return std::nullopt;
17206 return std::nullopt;
17209 for (
int I = 0; I < 2; ++I) {
17213 return std::nullopt;
17214 Args[I] = Converted.
get();
17221 return std::nullopt;
17224 return std::nullopt;
17226 TheCall->
setArg(0, Args[0]);
17227 TheCall->
setArg(1, Args[1]);
17238 TheCall->
getArg(1), Loc) ||
17240 TheCall->
getArg(2), Loc))
17244 for (
int I = 0; I < 3; ++I) {
17249 Args[I] = Converted.
get();
17252 int ArgOrdinal = 1;
17253 for (
Expr *Arg : Args) {
17255 ArgTyRestr, ArgOrdinal++))
17262 for (
int I = 0; I < 3; ++I)
17263 TheCall->
setArg(I, Args[I]);
17269bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17281bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17290 diag::err_builtin_invalid_arg_type)
17291 << 1 << 2 << 1 << 1 << TyArg;
17305 Expr *Matrix = MatrixArg.
get();
17307 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17310 << 1 << 3 << 0 << 0
17317 QualType ResultType =
Context.getConstantMatrixType(
17318 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17321 TheCall->
setType(ResultType);
17324 TheCall->
setArg(0, Matrix);
17329static std::optional<unsigned>
17337 uint64_t
Dim =
Value->getZExtValue();
17353 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17355 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17363 unsigned PtrArgIdx = 0;
17364 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17365 Expr *RowsExpr = TheCall->
getArg(1);
17366 Expr *ColumnsExpr = TheCall->
getArg(2);
17367 Expr *StrideExpr = TheCall->
getArg(3);
17369 bool ArgError =
false;
17376 PtrExpr = PtrConv.
get();
17377 TheCall->
setArg(0, PtrExpr);
17384 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17385 QualType ElementTy;
17388 << PtrArgIdx + 1 << 0 << 5 << 0
17392 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17396 << PtrArgIdx + 1 << 0 << 5
17403 auto ApplyArgumentConversions = [
this](Expr *E) {
17412 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17414 RowsExpr = RowsConv.
get();
17415 TheCall->
setArg(1, RowsExpr);
17417 RowsExpr =
nullptr;
17419 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17421 ColumnsExpr = ColumnsConv.
get();
17422 TheCall->
setArg(2, ColumnsExpr);
17424 ColumnsExpr =
nullptr;
17435 std::optional<unsigned> MaybeRows;
17439 std::optional<unsigned> MaybeColumns;
17444 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17447 StrideExpr = StrideConv.
get();
17448 TheCall->
setArg(3, StrideExpr);
17451 if (std::optional<llvm::APSInt>
Value =
17454 if (Stride < *MaybeRows) {
17456 diag::err_builtin_matrix_stride_too_small);
17462 if (ArgError || !MaybeRows || !MaybeColumns)
17466 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17477 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17479 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17487 unsigned PtrArgIdx = 1;
17488 Expr *MatrixExpr = TheCall->
getArg(0);
17489 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17490 Expr *StrideExpr = TheCall->
getArg(2);
17492 bool ArgError =
false;
17498 MatrixExpr = MatrixConv.
get();
17499 TheCall->
setArg(0, MatrixExpr);
17506 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17509 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17517 PtrExpr = PtrConv.
get();
17518 TheCall->
setArg(1, PtrExpr);
17526 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17529 << PtrArgIdx + 1 << 0 << 5 << 0
17533 QualType ElementTy = PtrTy->getPointeeType();
17535 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17540 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17542 diag::err_builtin_matrix_pointer_arg_mismatch)
17543 << ElementTy << MatrixTy->getElementType();
17558 StrideExpr = StrideConv.
get();
17559 TheCall->
setArg(2, StrideExpr);
17564 if (std::optional<llvm::APSInt>
Value =
17567 if (Stride < MatrixTy->getNumRows()) {
17569 diag::err_builtin_matrix_stride_too_small);
17589 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17594 llvm::StringSet<> CalleeTCBs;
17595 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17596 CalleeTCBs.insert(A->getTCBName());
17597 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17598 CalleeTCBs.insert(A->getTCBName());
17602 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17603 StringRef CallerTCB = A->getTCBName();
17604 if (CalleeTCBs.count(CallerTCB) == 0) {
17605 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17606 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
Defines enumerations for traits support.
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 getFunctionName(const CallEvent &Call)
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 ExprResult PointerAuthAuthWithPCAndResign(Sema &S, CallExpr *Call)
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.
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 hasUnrecoverableErrorOccurred() const
Determine whether any unrecoverable 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...
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.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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
ARM8_3Key
Hardware pointer-signing keys in ARM8.3.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
bool 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.
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
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,...
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)
SetTy< T > join(SetTy< T > A, SetTy< T > B, typename SetTy< T >::Factory &F)
Computes the union of two ImmutableSets.
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool hasSpecificAttr(const Container &container)
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ Success
Annotation was successful.
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
MutableArrayRef< Expr * > MultiExprArg
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
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.