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) {
1166 unsigned NewIndex = Index;
1168 unsigned DABIndices = DABAttr->argIndices_size();
1169 NewIndex = Index < DABIndices ? DABAttr->argIndices_begin()[Index]
1173 return std::nullopt;
1179 std::optional<llvm::APSInt> EvaluateIntegerArgument(
unsigned Index) {
1180 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1182 return std::nullopt;
1184 Expr *Arg = TheCall->
getArg(*IndexOptional);
1186 return std::nullopt;
1188 return Result.Val.getInt();
1191 std::optional<llvm::APSInt>
1192 ComputeExplicitObjectSizeArgument(
unsigned Index) {
1193 std::optional<llvm::APSInt>
Integer = EvaluateIntegerArgument(Index);
1195 return std::nullopt;
1201 std::optional<llvm::APSInt> ComputeSizeArgument(
unsigned Index) {
1207 if (Index < FD->getNumParams()) {
1208 if (
const auto *POS =
1210 BOSType = POS->getType();
1213 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1215 return std::nullopt;
1217 const Expr *ObjArg = TheCall->
getArg(*IndexOptional);
1218 if (std::optional<uint64_t> ObjSize =
1221 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1223 return std::nullopt;
1226 std::optional<llvm::APSInt>
1227 ComputeExplicitObjectSizeArgumentProduct(
unsigned LIndex,
unsigned RIndex) {
1228 auto L = ComputeExplicitObjectSizeArgument(LIndex);
1229 auto R = ComputeExplicitObjectSizeArgument(RIndex);
1231 return std::nullopt;
1234 2 * std::max({L->getBitWidth(),
R->getBitWidth(), SizeTypeWidth});
1236 llvm::APSInt
LE = L->extOrTrunc(W);
1237 llvm::APSInt RE =
R->extOrTrunc(W);
1242 std::optional<llvm::APSInt> ComputeStrLenArgument(
unsigned Index) {
1243 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1245 return std::nullopt;
1246 unsigned NewIndex = *IndexOptional;
1248 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1250 if (std::optional<uint64_t>
Result =
1253 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1255 return std::nullopt;
1258 unsigned getSizeTypeWidth()
const {
return SizeTypeWidth; }
1260 unsigned getBuiltinID()
const {
1261 const FunctionDecl *UseDecl = FD;
1263 UseDecl = DABAttr->getFunction();
1264 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1271 unsigned ID = getBuiltinID();
1275 assert(Callee &&
"expected callee");
1276 return Callee->getName().str();
1279 StringRef Ref = Name;
1281 if (!(Ref.consume_front(
"__builtin___") && Ref.consume_back(
"_chk")))
1282 Ref.consume_front(
"__builtin_");
1283 assert(!Ref.empty() &&
"expected non-empty function name");
1288 void checkSourceOverread(
unsigned SrcArgIdx,
unsigned SizeArgIdx) {
1292 const Expr *SrcArg = TheCall->
getArg(SrcArgIdx);
1293 const Expr *SizeArg = TheCall->
getArg(SizeArgIdx);
1298 std::optional<llvm::APSInt> CopyLen =
1299 ComputeExplicitObjectSizeArgument(SizeArgIdx);
1300 std::optional<llvm::APSInt> SrcBufSize = ComputeSizeArgument(SrcArgIdx);
1302 if (!CopyLen || !SrcBufSize)
1306 if (llvm::APSInt::compareValues(*CopyLen, *SrcBufSize) <= 0)
1310 S.
PDiag(diag::warn_stringop_overread)
1312 << SrcBufSize->getZExtValue());
1319 const DiagnoseAsBuiltinAttr *DABAttr;
1320 unsigned SizeTypeWidth;
1324void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1329 FortifiedBufferChecker Checker(*
this, FD, TheCall);
1331 unsigned BuiltinID = Checker.getBuiltinID();
1335 unsigned SizeTypeWidth = Checker.getSizeTypeWidth();
1337 std::optional<llvm::APSInt> AccessSize;
1338 std::optional<llvm::APSInt> BufferSize;
1339 unsigned DiagID = 0;
1341 switch (BuiltinID) {
1344 case Builtin::BI__builtin_strcat:
1345 case Builtin::BIstrcat:
1346 case Builtin::BI__builtin_stpcpy:
1347 case Builtin::BIstpcpy:
1348 case Builtin::BI__builtin_strcpy:
1349 case Builtin::BIstrcpy: {
1350 DiagID = diag::warn_fortify_strlen_overflow;
1351 AccessSize = Checker.ComputeStrLenArgument(1);
1352 BufferSize = Checker.ComputeSizeArgument(0);
1356 case Builtin::BI__builtin___strcat_chk:
1357 case Builtin::BI__builtin___stpcpy_chk:
1358 case Builtin::BI__builtin___strcpy_chk: {
1359 DiagID = diag::warn_fortify_strlen_overflow;
1360 AccessSize = Checker.ComputeStrLenArgument(1);
1361 BufferSize = Checker.ComputeExplicitObjectSizeArgument(2);
1365 case Builtin::BIscanf:
1366 case Builtin::BIfscanf:
1367 case Builtin::BIsscanf: {
1368 unsigned FormatIndex = 1;
1369 unsigned DataIndex = 2;
1370 if (BuiltinID == Builtin::BIscanf) {
1375 const auto *FormatExpr =
1378 StringRef FormatStrRef;
1383 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1384 unsigned SourceSize) {
1385 DiagID = diag::warn_fortify_scanf_overflow;
1386 unsigned Index = ArgIndex + DataIndex;
1387 std::string FunctionName = Checker.getFunctionName();
1389 PDiag(DiagID) << FunctionName << (Index + 1)
1390 << DestSize << SourceSize);
1393 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1394 return Checker.ComputeSizeArgument(Index + DataIndex);
1396 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1397 const char *FormatBytes = FormatStrRef.data();
1408 case Builtin::BIsprintf:
1409 case Builtin::BI__builtin_sprintf:
1410 case Builtin::BI__builtin___sprintf_chk:
1411 case Builtin::BIvsprintf:
1412 case Builtin::BI__builtin_vsprintf:
1413 case Builtin::BI__builtin___vsprintf_chk: {
1414 bool IsChk = BuiltinID == Builtin::BI__builtin___sprintf_chk ||
1415 BuiltinID == Builtin::BI__builtin___vsprintf_chk;
1416 std::optional<unsigned> FormatIndex = Checker.TranslateIndex(IsChk ? 3 : 1);
1419 const auto *FormatExpr =
1422 StringRef FormatStrRef;
1425 EstimateSizeFormatHandler H(FormatStrRef);
1426 const char *FormatBytes = FormatStrRef.data();
1428 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1429 Context.getTargetInfo(),
false)) {
1430 DiagID = H.isKernelCompatible()
1431 ? diag::warn_format_overflow
1432 : diag::warn_format_overflow_non_kprintf;
1433 AccessSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1434 .extOrTrunc(SizeTypeWidth);
1436 BufferSize = Checker.ComputeExplicitObjectSizeArgument(2);
1438 BufferSize = Checker.ComputeSizeArgument(0);
1445 case Builtin::BI__builtin___memcpy_chk:
1446 case Builtin::BI__builtin___memmove_chk:
1447 case Builtin::BI__builtin___memset_chk:
1448 case Builtin::BI__builtin___strlcat_chk:
1449 case Builtin::BI__builtin___strlcpy_chk:
1450 case Builtin::BI__builtin___strncat_chk:
1451 case Builtin::BI__builtin___strncpy_chk:
1452 case Builtin::BI__builtin___stpncpy_chk:
1453 case Builtin::BI__builtin___memccpy_chk:
1454 case Builtin::BI__builtin___mempcpy_chk: {
1455 DiagID = diag::warn_builtin_chk_overflow;
1457 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1459 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1461 if (BuiltinID == Builtin::BI__builtin___memcpy_chk ||
1462 BuiltinID == Builtin::BI__builtin___memmove_chk ||
1463 BuiltinID == Builtin::BI__builtin___mempcpy_chk) {
1464 Checker.checkSourceOverread(1, 2);
1469 case Builtin::BI__builtin___snprintf_chk:
1470 case Builtin::BI__builtin___vsnprintf_chk: {
1471 DiagID = diag::warn_builtin_chk_overflow;
1472 AccessSize = Checker.ComputeExplicitObjectSizeArgument(1);
1473 BufferSize = Checker.ComputeExplicitObjectSizeArgument(3);
1477 case Builtin::BIstrncat:
1478 case Builtin::BI__builtin_strncat:
1479 case Builtin::BIstrncpy:
1480 case Builtin::BI__builtin_strncpy:
1481 case Builtin::BIstpncpy:
1482 case Builtin::BI__builtin_stpncpy:
1483 case Builtin::BIstrlcat:
1484 case Builtin::BI__builtin_strlcat:
1485 case Builtin::BIstrlcpy:
1486 case Builtin::BI__builtin_strlcpy: {
1492 DiagID = diag::warn_fortify_source_size_mismatch;
1494 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1495 BufferSize = Checker.ComputeSizeArgument(0);
1499 case Builtin::BIrecv:
1500 case Builtin::BIrecvfrom: {
1501 unsigned ExpectedArgs = BuiltinID == Builtin::BIrecv ? 4 : 6;
1506 DiagID = diag::warn_fortify_source_size_mismatch;
1507 AccessSize = Checker.ComputeExplicitObjectSizeArgument(2);
1508 BufferSize = Checker.ComputeSizeArgument(1);
1512 case Builtin::BIpoll:
1513 case Builtin::BIppoll:
1514 case Builtin::BIppoll64: {
1515 unsigned ExpectedArgs = BuiltinID == Builtin::BIpoll ? 3 : 4;
1525 if (BuiltinID == Builtin::BIpoll) {
1530 if (TmoPointeeTy.
isNull())
1537 std::optional<CharUnits> ElemSize =
1538 Context.getTypeSizeInCharsIfKnown(PointeeTy);
1541 std::optional<llvm::APSInt> Count =
1542 Checker.ComputeExplicitObjectSizeArgument(1);
1545 DiagID = diag::warn_fortify_source_size_mismatch;
1546 unsigned WideWidth = SizeTypeWidth * 2;
1547 AccessSize = Count->extOrTrunc(WideWidth) *
1548 llvm::APSInt(llvm::APInt(WideWidth, ElemSize->getQuantity()),
1550 BufferSize = Checker.ComputeSizeArgument(0);
1554 case Builtin::BIbzero:
1555 case Builtin::BI__builtin_bzero:
1556 case Builtin::BImemcpy:
1557 case Builtin::BI__builtin_memcpy:
1558 case Builtin::BImemmove:
1559 case Builtin::BI__builtin_memmove:
1560 case Builtin::BImemset:
1561 case Builtin::BI__builtin_memset:
1562 case Builtin::BImempcpy:
1563 case Builtin::BI__builtin_mempcpy: {
1564 DiagID = diag::warn_fortify_source_overflow;
1566 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1567 BufferSize = Checker.ComputeSizeArgument(0);
1570 if (BuiltinID != Builtin::BImemset &&
1571 BuiltinID != Builtin::BI__builtin_memset &&
1572 BuiltinID != Builtin::BIbzero &&
1573 BuiltinID != Builtin::BI__builtin_bzero) {
1574 Checker.checkSourceOverread(1, 2);
1578 case Builtin::BIbcopy:
1579 case Builtin::BI__builtin_bcopy: {
1580 DiagID = diag::warn_fortify_source_overflow;
1582 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1583 BufferSize = Checker.ComputeSizeArgument(1);
1584 Checker.checkSourceOverread(0, 2);
1587 case Builtin::BIfread: {
1588 DiagID = diag::warn_fortify_source_overflow;
1589 AccessSize = Checker.ComputeExplicitObjectSizeArgumentProduct(1, 2);
1590 BufferSize = Checker.ComputeSizeArgument(0);
1593 case Builtin::BIfwrite: {
1594 DiagID = diag::warn_fortify_source_overread;
1595 AccessSize = Checker.ComputeExplicitObjectSizeArgumentProduct(1, 2);
1596 BufferSize = Checker.ComputeSizeArgument(0);
1599 case Builtin::BIfgets: {
1600 AccessSize = Checker.EvaluateIntegerArgument(1);
1602 if (AccessSize && AccessSize->isNegative()) {
1604 PDiag(diag::warn_fortify_source_negative_size)
1605 << Checker.getFunctionName());
1609 DiagID = diag::warn_fortify_source_size_mismatch;
1610 BufferSize = Checker.ComputeSizeArgument(0);
1614 case Builtin::BImemchr:
1615 case Builtin::BI__builtin_memchr: {
1616 Checker.checkSourceOverread(0, 2);
1622 case Builtin::BImemcmp:
1623 case Builtin::BI__builtin_memcmp:
1624 case Builtin::BIbcmp:
1625 case Builtin::BI__builtin_bcmp: {
1626 Checker.checkSourceOverread(0, 2);
1627 Checker.checkSourceOverread(1, 2);
1630 case Builtin::BIsnprintf:
1631 case Builtin::BI__builtin_snprintf:
1632 case Builtin::BIvsnprintf:
1633 case Builtin::BI__builtin_vsnprintf: {
1634 DiagID = diag::warn_fortify_source_size_mismatch;
1635 AccessSize = Checker.ComputeExplicitObjectSizeArgument(1);
1637 StringRef FormatStrRef;
1641 EstimateSizeFormatHandler H(FormatStrRef);
1642 const char *FormatBytes = FormatStrRef.data();
1644 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1645 Context.getTargetInfo(),
false)) {
1646 llvm::APSInt FormatSize =
1647 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1648 .extOrTrunc(SizeTypeWidth);
1649 if (FormatSize > *AccessSize && *AccessSize != 0) {
1650 unsigned TruncationDiagID =
1651 H.isKernelCompatible() ? diag::warn_format_truncation
1652 : diag::warn_format_truncation_non_kprintf;
1653 SmallString<16> SpecifiedSizeStr;
1654 SmallString<16> FormatSizeStr;
1655 AccessSize->toString(SpecifiedSizeStr, 10);
1656 FormatSize.toString(FormatSizeStr, 10);
1658 PDiag(TruncationDiagID)
1659 << Checker.getFunctionName()
1660 << SpecifiedSizeStr << FormatSizeStr);
1664 BufferSize = Checker.ComputeSizeArgument(0);
1668 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1672 if (!AccessSize || !BufferSize ||
1673 llvm::APSInt::compareValues(*AccessSize, *BufferSize) <= 0)
1676 std::string FunctionName = Checker.getFunctionName();
1678 SmallString<16> BufferSizeStr;
1679 SmallString<16> AccessSizeStr;
1680 BufferSize->toString(BufferSizeStr, 10);
1681 AccessSize->toString(AccessSizeStr, 10);
1684 << FunctionName << BufferSizeStr << AccessSizeStr);
1704 Expr *Arg = TheCall->
getArg(0);
1712 llvm::APInt RawValue =
R.Val.getInt();
1713 llvm::APInt Mask(RawValue.getBitWidth(), 0777);
1714 llvm::APInt
Extra = RawValue & ~Mask;
1717 SmallString<16> ExtraStr;
1718 Extra.toString(ExtraStr, 8,
false);
1735 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1738 << DRE->getDecl()->getIdentifier();
1750 "__builtin_alloca has invalid address space");
1776enum PointerAuthOpKind {
1792 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1823 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1826 llvm::raw_svector_ostream Str(
Value);
1835 Result = KeyValue->getZExtValue();
1854 bool IsAddrDiscArg =
false;
1859 IsAddrDiscArg =
true;
1868 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1869 <<
Result->getExtValue();
1871 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1877 IntVal =
Result->getZExtValue();
1881static std::pair<const ValueDecl *, CharUnits>
1888 const auto *BaseDecl =
1893 return {BaseDecl,
Result.Val.getLValueOffset()};
1897 bool RequireConstant =
false) {
1905 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1906 return OpKind != PAO_BlendInteger;
1908 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1909 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1910 OpKind == PAO_SignGeneric || OpKind == PAO_BlendPC;
1919 }
else if (AllowsInteger(OpKind) &&
1926 <<
unsigned(OpKind == PAO_Discriminator ? 1
1927 : OpKind == PAO_BlendPointer ? 2
1928 : OpKind == PAO_BlendInteger ? 3
1929 : OpKind == PAO_BlendPC ? 4
1931 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1941 if (!RequireConstant) {
1943 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1946 ? diag::warn_ptrauth_sign_null_pointer
1947 : diag::warn_ptrauth_auth_null_pointer)
1957 if (OpKind == PAO_Sign) {
1975 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1980 assert(OpKind == PAO_Discriminator);
1986 if (
Call->getBuiltinCallee() ==
1987 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2002 assert(
Pointer->getType()->isPointerType());
2014 assert(
Integer->getType()->isIntegerType());
2020 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
2033 Call->setType(
Call->getArgs()[0]->getType());
2064 PointerAuthOpKind OpKind,
2065 bool RequireConstant) {
2076 Call->setType(
Call->getArgs()[0]->getType());
2092 Call->setType(
Call->getArgs()[0]->getType());
2113 unsigned OldKey = 0;
2116 if (OldKey !=
static_cast<unsigned>(AK::ASIA) &&
2117 OldKey !=
static_cast<unsigned>(AK::ASIB)) {
2118 S.
Diag(
Call->getArgs()[1]->getExprLoc(),
2119 diag::err_ptrauth_auth_with_pc_and_resign_invalid_key)
2120 << OldKey <<
Call->getArgs()[1]->getSourceRange();
2125 Call->setType(
Call->getArgs()[0]->getType());
2134 const Expr *AddendExpr =
Call->getArg(5);
2136 if (!AddendIsConstInt) {
2137 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
2151 Call->setType(
Call->getArgs()[0]->getType());
2160 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
2163 const auto *Literal = dyn_cast<StringLiteral>(Arg);
2164 if (!Literal || Literal->getCharByteWidth() != 1) {
2180 Call->setArg(0, FirstValue.
get());
2186 if (!FirstArgRecord) {
2187 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2188 << 0 << FirstArgType;
2193 diag::err_get_vtable_pointer_requires_complete_type)) {
2198 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2199 << 1 << FirstArgRecord;
2203 Call->setType(ReturnType);
2228 auto DiagSelect = [&]() -> std::optional<unsigned> {
2235 return std::optional<unsigned>{};
2250 diag::err_incomplete_type))
2254 "Unhandled non-object pointer case");
2282 if (PT->getPointeeType()->isFunctionType()) {
2284 diag::err_builtin_is_within_lifetime_invalid_arg)
2290 if (PT->getPointeeType()->isVariableArrayType()) {
2292 << 1 <<
"__builtin_is_within_lifetime";
2297 diag::err_builtin_is_within_lifetime_invalid_arg)
2311 diag::err_builtin_trivially_relocate_invalid_arg_type)
2318 diag::err_incomplete_type))
2322 T->isIncompleteArrayType()) {
2324 diag::err_builtin_trivially_relocate_invalid_arg_type)
2325 << (
T.isConstQualified() ? 1 : 2);
2334 diag::err_builtin_trivially_relocate_invalid_arg_type)
2341 if (Size.isInvalid())
2345 if (Size.isInvalid())
2347 SizeExpr = Size.get();
2348 TheCall->
setArg(2, SizeExpr);
2358 llvm::Triple::ObjectFormatType CurObjFormat =
2360 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2373 llvm::Triple::ArchType CurArch =
2375 if (llvm::is_contained(SupportedArchs, CurArch))
2385bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2392 case llvm::Triple::arm:
2393 case llvm::Triple::armeb:
2394 case llvm::Triple::thumb:
2395 case llvm::Triple::thumbeb:
2397 case llvm::Triple::aarch64:
2398 case llvm::Triple::aarch64_32:
2399 case llvm::Triple::aarch64_be:
2401 case llvm::Triple::bpfeb:
2402 case llvm::Triple::bpfel:
2404 case llvm::Triple::dxil:
2406 case llvm::Triple::hexagon:
2408 case llvm::Triple::mips:
2409 case llvm::Triple::mipsel:
2410 case llvm::Triple::mips64:
2411 case llvm::Triple::mips64el:
2413 case llvm::Triple::spirv:
2414 case llvm::Triple::spirv32:
2415 case llvm::Triple::spirv64:
2416 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2419 case llvm::Triple::systemz:
2421 case llvm::Triple::x86:
2422 case llvm::Triple::x86_64:
2424 case llvm::Triple::ppc:
2425 case llvm::Triple::ppcle:
2426 case llvm::Triple::ppc64:
2427 case llvm::Triple::ppc64le:
2429 case llvm::Triple::amdgpu:
2431 case llvm::Triple::riscv32:
2432 case llvm::Triple::riscv64:
2433 case llvm::Triple::riscv32be:
2434 case llvm::Triple::riscv64be:
2436 case llvm::Triple::loongarch32:
2437 case llvm::Triple::loongarch64:
2440 case llvm::Triple::wasm32:
2441 case llvm::Triple::wasm64:
2443 case llvm::Triple::nvptx:
2444 case llvm::Triple::nvptx64:
2450 return T->isDependentType() ||
2451 (
T->isRealType() && !
T->isBooleanType() && !
T->isEnumeralType());
2466 switch (ArgTyRestr) {
2470 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2471 << ArgOrdinal << 2 << 1 << 1
2478 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2479 << ArgOrdinal << 5 << 0
2485 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2486 << ArgOrdinal << 5 << 1
2492 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2506 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2507 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2508 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2509 "Expecting __builtin_cpu_...");
2511 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2513 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2514 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2515 (!IsCPUSupports && TInfo->supportsCpuIs()));
2517 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2524 ? diag::err_builtin_aix_os_unsupported
2525 : diag::err_builtin_target_unsupported)
2531 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2569 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2570 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2571 BT->getNumBits() != 1) {
2573 << ArgTy << BT->getNumBits();
2649 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2652 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2661 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2662 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2682 TheCall->
setArg(0, Arg0);
2699 TheCall->
setArg(1, Arg1);
2705 << 2 << 1 << 4 << 0 << Arg1Ty;
2719 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2721 << (OnlyUnsigned ? 3 : 1)
2729 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2732 return OnlyUnsigned ?
T->isUnsignedIntegerType() :
T->isIntegerType();
2737 return emitError(S, Loc,
T);
2742 return emitError(S, Loc,
T);
2748 return emitError(S, Loc,
T);
2753 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2758 return emitError(S, Loc,
T);
2763 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2769 llvm_unreachable(
"conversion functions are permitted");
2788 TheCall->
setArg(0, Arg0);
2802 TheCall->
setArg(1, Arg1);
2813 unsigned Pos,
bool AllowConst,
2817 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2822 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2823 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2824 << Pos <<
"scalar pointer";
2833 diag::err_typecheck_convert_incompatible)
2842 bool TypeDependent =
false;
2843 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2871 Builtin::BI__builtin_masked_load))
2885 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2908 Builtin::BI__builtin_masked_store))
2916 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2927 << MaskTy << ValTy);
2931 PtrTy->getPointeeType().getUnqualifiedType()))
2933 diag::err_vec_builtin_incompatible_vector)
2962 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2975 << MaskTy << IdxTy);
2984 diag::err_vec_masked_load_store_ptr)
3013 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
3028 << MaskTy << IdxTy);
3034 << MaskTy << ValTy);
3037 PtrTy->getPointeeType().getUnqualifiedType()))
3039 diag::err_vec_builtin_incompatible_vector)
3053 if (Args.size() == 0) {
3055 diag::err_typecheck_call_too_few_args_at_least)
3061 QualType FuncT = Args[0]->getType();
3064 if (Args.size() < 2) {
3066 diag::err_typecheck_call_too_few_args_at_least)
3072 const Type *MemPtrClass = MPT->getQualifier().getAsType();
3073 QualType ObjectT = Args[1]->getType();
3075 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
3124 tok::periodstar, ObjectArg.
get(), Args[0]);
3128 if (MPT->isMemberDataPointer())
3132 auto *MemCall =
new (S.
Context)
3156 return TyA->getElementType();
3163Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
3168 unsigned ICEArguments = 0;
3170 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
3175 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
3177 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
3182 if (ArgNo < TheCall->getNumArgs() &&
3185 ICEArguments &= ~(1 << ArgNo);
3189 switch (BuiltinID) {
3190 case Builtin::BI__builtin___get_unsafe_stack_start:
3191 case Builtin::BI__builtin___get_unsafe_stack_bottom:
3193 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3194 <<
"__safestack_get_unsafe_stack_bottom";
3196 case Builtin::BI__builtin___get_unsafe_stack_top:
3198 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3199 <<
"__safestack_get_unsafe_stack_top";
3201 case Builtin::BI__builtin___get_unsafe_stack_ptr:
3203 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3204 <<
"__safestack_get_unsafe_stack_ptr";
3206 case Builtin::BI__builtin_cpu_supports:
3207 case Builtin::BI__builtin_cpu_is:
3209 Context.getAuxTargetInfo(), BuiltinID))
3212 case Builtin::BI__builtin_cpu_init:
3213 if (!
Context.getTargetInfo().supportsCpuInit()) {
3219 case Builtin::BI__builtin___CFStringMakeConstantString:
3223 *
this, BuiltinID, TheCall,
3224 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
3227 "Wrong # arguments to builtin CFStringMakeConstantString");
3228 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
3231 case Builtin::BI__builtin_ms_va_start:
3232 case Builtin::BI__builtin_zos_va_start:
3233 case Builtin::BI__builtin_stdarg_start:
3234 case Builtin::BI__builtin_va_start:
3235 case Builtin::BI__builtin_c23_va_start:
3236 if (BuiltinVAStart(BuiltinID, TheCall))
3239 case Builtin::BI__va_start: {
3240 switch (
Context.getTargetInfo().getTriple().getArch()) {
3241 case llvm::Triple::aarch64:
3242 case llvm::Triple::arm:
3243 case llvm::Triple::thumb:
3244 if (BuiltinVAStartARMMicrosoft(TheCall))
3248 if (BuiltinVAStart(BuiltinID, TheCall))
3256 case Builtin::BI_interlockedbittestandset_acq:
3257 case Builtin::BI_interlockedbittestandset_rel:
3258 case Builtin::BI_interlockedbittestandset_nf:
3259 case Builtin::BI_interlockedbittestandreset_acq:
3260 case Builtin::BI_interlockedbittestandreset_rel:
3261 case Builtin::BI_interlockedbittestandreset_nf:
3264 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3269 case Builtin::BI_bittest64:
3270 case Builtin::BI_bittestandcomplement64:
3271 case Builtin::BI_bittestandreset64:
3272 case Builtin::BI_bittestandset64:
3273 case Builtin::BI_interlockedbittestandreset64:
3274 case Builtin::BI_interlockedbittestandset64:
3277 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3278 llvm::Triple::aarch64, llvm::Triple::amdgpu}))
3283 case Builtin::BI_interlockedbittestandreset64_acq:
3284 case Builtin::BI_interlockedbittestandreset64_rel:
3285 case Builtin::BI_interlockedbittestandreset64_nf:
3286 case Builtin::BI_interlockedbittestandset64_acq:
3287 case Builtin::BI_interlockedbittestandset64_rel:
3288 case Builtin::BI_interlockedbittestandset64_nf:
3293 case Builtin::BI__builtin_set_flt_rounds:
3296 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3297 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgpu,
3298 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3299 llvm::Triple::ppc64le}))
3303 case Builtin::BI__builtin_isgreater:
3304 case Builtin::BI__builtin_isgreaterequal:
3305 case Builtin::BI__builtin_isless:
3306 case Builtin::BI__builtin_islessequal:
3307 case Builtin::BI__builtin_islessgreater:
3308 case Builtin::BI__builtin_isunordered:
3309 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3312 case Builtin::BI__builtin_fpclassify:
3313 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3316 case Builtin::BI__builtin_isfpclass:
3317 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3320 case Builtin::BI__builtin_isfinite:
3321 case Builtin::BI__builtin_isinf:
3322 case Builtin::BI__builtin_isinf_sign:
3323 case Builtin::BI__builtin_isnan:
3324 case Builtin::BI__builtin_issignaling:
3325 case Builtin::BI__builtin_isnormal:
3326 case Builtin::BI__builtin_issubnormal:
3327 case Builtin::BI__builtin_iszero:
3328 case Builtin::BI__builtin_signbit:
3329 case Builtin::BI__builtin_signbitf:
3330 case Builtin::BI__builtin_signbitl:
3331 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3334 case Builtin::BI__builtin_shufflevector:
3338 case Builtin::BI__builtin_masked_load:
3339 case Builtin::BI__builtin_masked_expand_load:
3341 case Builtin::BI__builtin_masked_store:
3342 case Builtin::BI__builtin_masked_compress_store:
3344 case Builtin::BI__builtin_masked_gather:
3346 case Builtin::BI__builtin_masked_scatter:
3348 case Builtin::BI__builtin_invoke:
3350 case Builtin::BI__builtin_prefetch:
3351 if (BuiltinPrefetch(TheCall))
3354 case Builtin::BI__builtin_alloca_with_align:
3355 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3356 if (BuiltinAllocaWithAlign(TheCall))
3359 case Builtin::BI__builtin_alloca:
3360 case Builtin::BI__builtin_alloca_uninitialized:
3367 case Builtin::BI__builtin_infer_alloc_token:
3371 case Builtin::BI__arithmetic_fence:
3372 if (BuiltinArithmeticFence(TheCall))
3375 case Builtin::BI__assume:
3376 case Builtin::BI__builtin_assume:
3377 if (BuiltinAssume(TheCall))
3380 case Builtin::BI__builtin_assume_aligned:
3381 if (BuiltinAssumeAligned(TheCall))
3384 case Builtin::BI__builtin_dynamic_object_size:
3385 case Builtin::BI__builtin_object_size:
3389 case Builtin::BI__builtin_longjmp:
3390 if (BuiltinLongjmp(TheCall))
3393 case Builtin::BI__builtin_setjmp:
3394 if (BuiltinSetjmp(TheCall))
3397 case Builtin::BI__builtin_complex:
3398 if (BuiltinComplex(TheCall))
3401 case Builtin::BI__builtin_classify_type:
3402 case Builtin::BI__builtin_constant_p: {
3411 case Builtin::BI__builtin_launder:
3413 case Builtin::BI__builtin_is_within_lifetime:
3415 case Builtin::BI__builtin_trivially_relocate:
3417 case Builtin::BI__builtin_clear_padding: {
3421 const Expr *PtrArg = TheCall->
getArg(0);
3422 const QualType PtrArgType = PtrArg->
getType();
3425 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3436 diag::err_typecheck_decl_incomplete_type))
3442 auto IsAddrOfDeclExpr = [&]() {
3444 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3445 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3449 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3450 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3454 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3455 if (!VarDecl || VarDecl->getType()->isReferenceType())
3460 QualType VarQType = VarDecl->getType();
3462 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3467 && !IsAddrOfDeclExpr()) {
3468 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3475 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3482 case Builtin::BI__sync_fetch_and_add:
3483 case Builtin::BI__sync_fetch_and_add_1:
3484 case Builtin::BI__sync_fetch_and_add_2:
3485 case Builtin::BI__sync_fetch_and_add_4:
3486 case Builtin::BI__sync_fetch_and_add_8:
3487 case Builtin::BI__sync_fetch_and_add_16:
3488 case Builtin::BI__sync_fetch_and_sub:
3489 case Builtin::BI__sync_fetch_and_sub_1:
3490 case Builtin::BI__sync_fetch_and_sub_2:
3491 case Builtin::BI__sync_fetch_and_sub_4:
3492 case Builtin::BI__sync_fetch_and_sub_8:
3493 case Builtin::BI__sync_fetch_and_sub_16:
3494 case Builtin::BI__sync_fetch_and_or:
3495 case Builtin::BI__sync_fetch_and_or_1:
3496 case Builtin::BI__sync_fetch_and_or_2:
3497 case Builtin::BI__sync_fetch_and_or_4:
3498 case Builtin::BI__sync_fetch_and_or_8:
3499 case Builtin::BI__sync_fetch_and_or_16:
3500 case Builtin::BI__sync_fetch_and_and:
3501 case Builtin::BI__sync_fetch_and_and_1:
3502 case Builtin::BI__sync_fetch_and_and_2:
3503 case Builtin::BI__sync_fetch_and_and_4:
3504 case Builtin::BI__sync_fetch_and_and_8:
3505 case Builtin::BI__sync_fetch_and_and_16:
3506 case Builtin::BI__sync_fetch_and_xor:
3507 case Builtin::BI__sync_fetch_and_xor_1:
3508 case Builtin::BI__sync_fetch_and_xor_2:
3509 case Builtin::BI__sync_fetch_and_xor_4:
3510 case Builtin::BI__sync_fetch_and_xor_8:
3511 case Builtin::BI__sync_fetch_and_xor_16:
3512 case Builtin::BI__sync_fetch_and_nand:
3513 case Builtin::BI__sync_fetch_and_nand_1:
3514 case Builtin::BI__sync_fetch_and_nand_2:
3515 case Builtin::BI__sync_fetch_and_nand_4:
3516 case Builtin::BI__sync_fetch_and_nand_8:
3517 case Builtin::BI__sync_fetch_and_nand_16:
3518 case Builtin::BI__sync_add_and_fetch:
3519 case Builtin::BI__sync_add_and_fetch_1:
3520 case Builtin::BI__sync_add_and_fetch_2:
3521 case Builtin::BI__sync_add_and_fetch_4:
3522 case Builtin::BI__sync_add_and_fetch_8:
3523 case Builtin::BI__sync_add_and_fetch_16:
3524 case Builtin::BI__sync_sub_and_fetch:
3525 case Builtin::BI__sync_sub_and_fetch_1:
3526 case Builtin::BI__sync_sub_and_fetch_2:
3527 case Builtin::BI__sync_sub_and_fetch_4:
3528 case Builtin::BI__sync_sub_and_fetch_8:
3529 case Builtin::BI__sync_sub_and_fetch_16:
3530 case Builtin::BI__sync_and_and_fetch:
3531 case Builtin::BI__sync_and_and_fetch_1:
3532 case Builtin::BI__sync_and_and_fetch_2:
3533 case Builtin::BI__sync_and_and_fetch_4:
3534 case Builtin::BI__sync_and_and_fetch_8:
3535 case Builtin::BI__sync_and_and_fetch_16:
3536 case Builtin::BI__sync_or_and_fetch:
3537 case Builtin::BI__sync_or_and_fetch_1:
3538 case Builtin::BI__sync_or_and_fetch_2:
3539 case Builtin::BI__sync_or_and_fetch_4:
3540 case Builtin::BI__sync_or_and_fetch_8:
3541 case Builtin::BI__sync_or_and_fetch_16:
3542 case Builtin::BI__sync_xor_and_fetch:
3543 case Builtin::BI__sync_xor_and_fetch_1:
3544 case Builtin::BI__sync_xor_and_fetch_2:
3545 case Builtin::BI__sync_xor_and_fetch_4:
3546 case Builtin::BI__sync_xor_and_fetch_8:
3547 case Builtin::BI__sync_xor_and_fetch_16:
3548 case Builtin::BI__sync_nand_and_fetch:
3549 case Builtin::BI__sync_nand_and_fetch_1:
3550 case Builtin::BI__sync_nand_and_fetch_2:
3551 case Builtin::BI__sync_nand_and_fetch_4:
3552 case Builtin::BI__sync_nand_and_fetch_8:
3553 case Builtin::BI__sync_nand_and_fetch_16:
3554 case Builtin::BI__sync_val_compare_and_swap:
3555 case Builtin::BI__sync_val_compare_and_swap_1:
3556 case Builtin::BI__sync_val_compare_and_swap_2:
3557 case Builtin::BI__sync_val_compare_and_swap_4:
3558 case Builtin::BI__sync_val_compare_and_swap_8:
3559 case Builtin::BI__sync_val_compare_and_swap_16:
3560 case Builtin::BI__sync_bool_compare_and_swap:
3561 case Builtin::BI__sync_bool_compare_and_swap_1:
3562 case Builtin::BI__sync_bool_compare_and_swap_2:
3563 case Builtin::BI__sync_bool_compare_and_swap_4:
3564 case Builtin::BI__sync_bool_compare_and_swap_8:
3565 case Builtin::BI__sync_bool_compare_and_swap_16:
3566 case Builtin::BI__sync_lock_test_and_set:
3567 case Builtin::BI__sync_lock_test_and_set_1:
3568 case Builtin::BI__sync_lock_test_and_set_2:
3569 case Builtin::BI__sync_lock_test_and_set_4:
3570 case Builtin::BI__sync_lock_test_and_set_8:
3571 case Builtin::BI__sync_lock_test_and_set_16:
3572 case Builtin::BI__sync_lock_release:
3573 case Builtin::BI__sync_lock_release_1:
3574 case Builtin::BI__sync_lock_release_2:
3575 case Builtin::BI__sync_lock_release_4:
3576 case Builtin::BI__sync_lock_release_8:
3577 case Builtin::BI__sync_lock_release_16:
3578 case Builtin::BI__sync_swap:
3579 case Builtin::BI__sync_swap_1:
3580 case Builtin::BI__sync_swap_2:
3581 case Builtin::BI__sync_swap_4:
3582 case Builtin::BI__sync_swap_8:
3583 case Builtin::BI__sync_swap_16:
3584 return BuiltinAtomicOverloaded(TheCallResult);
3585 case Builtin::BI__sync_synchronize:
3589 case Builtin::BI__builtin_nontemporal_load:
3590 case Builtin::BI__builtin_nontemporal_store:
3591 return BuiltinNontemporalOverloaded(TheCallResult);
3592 case Builtin::BI__builtin_memcpy_inline: {
3593 clang::Expr *SizeOp = TheCall->
getArg(2);
3605 case Builtin::BI__builtin_memset_inline: {
3606 clang::Expr *SizeOp = TheCall->
getArg(2);
3616#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3617 case Builtin::BI##ID: \
3618 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3619#include "clang/Basic/Builtins.inc"
3620 case Builtin::BI__annotation: {
3621 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3622 if (!TT.isOSWindows() && !TT.isUEFI()) {
3631 case Builtin::BI__builtin_annotation:
3635 case Builtin::BI__builtin_addressof:
3639 case Builtin::BI__builtin_function_start:
3643 case Builtin::BI__builtin_is_aligned:
3644 case Builtin::BI__builtin_align_up:
3645 case Builtin::BI__builtin_align_down:
3649 case Builtin::BI__builtin_add_overflow:
3650 case Builtin::BI__builtin_sub_overflow:
3651 case Builtin::BI__builtin_mul_overflow:
3655 case Builtin::BI__builtin_operator_new:
3656 case Builtin::BI__builtin_operator_delete: {
3657 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3659 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3662 case Builtin::BI__builtin_dump_struct:
3664 case Builtin::BI__builtin_expect_with_probability: {
3669 const Expr *ProbArg = TheCall->
getArg(2);
3670 SmallVector<PartialDiagnosticAt, 8> Notes;
3671 Expr::EvalResult Eval;
3675 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3682 bool LoseInfo =
false;
3683 Probability.convert(llvm::APFloat::IEEEdouble(),
3684 llvm::RoundingMode::Dynamic, &LoseInfo);
3685 if (!(Probability >= llvm::APFloat(0.0) &&
3686 Probability <= llvm::APFloat(1.0))) {
3693 case Builtin::BI__builtin_preserve_access_index:
3697 case Builtin::BI__builtin_call_with_static_chain:
3701 case Builtin::BI__exception_code:
3702 case Builtin::BI_exception_code:
3704 diag::err_seh___except_block))
3707 case Builtin::BI__exception_info:
3708 case Builtin::BI_exception_info:
3710 diag::err_seh___except_filter))
3713 case Builtin::BI__GetExceptionInfo:
3725 case Builtin::BIaddressof:
3726 case Builtin::BI__addressof:
3727 case Builtin::BIforward:
3728 case Builtin::BIforward_like:
3729 case Builtin::BImove:
3730 case Builtin::BImove_if_noexcept:
3731 case Builtin::BIas_const: {
3739 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3740 BuiltinID == Builtin::BI__addressof;
3742 (ReturnsPointer ?
Result->isAnyPointerType()
3743 :
Result->isReferenceType()) &&
3746 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3752 case Builtin::BI__builtin_ptrauth_strip:
3754 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3756 case Builtin::BI__builtin_ptrauth_sign_constant:
3759 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3762 case Builtin::BI__builtin_ptrauth_auth:
3765 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3767 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3769 case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
3771 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3773 case Builtin::BI__builtin_ptrauth_string_discriminator:
3776 case Builtin::BI__builtin_get_vtable_pointer:
3780 case Builtin::BIread_pipe:
3781 case Builtin::BIwrite_pipe:
3784 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3787 case Builtin::BIreserve_read_pipe:
3788 case Builtin::BIreserve_write_pipe:
3789 case Builtin::BIwork_group_reserve_read_pipe:
3790 case Builtin::BIwork_group_reserve_write_pipe:
3791 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3794 case Builtin::BIsub_group_reserve_read_pipe:
3795 case Builtin::BIsub_group_reserve_write_pipe:
3796 if (
OpenCL().checkSubgroupExt(TheCall) ||
3797 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3800 case Builtin::BIcommit_read_pipe:
3801 case Builtin::BIcommit_write_pipe:
3802 case Builtin::BIwork_group_commit_read_pipe:
3803 case Builtin::BIwork_group_commit_write_pipe:
3804 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3807 case Builtin::BIsub_group_commit_read_pipe:
3808 case Builtin::BIsub_group_commit_write_pipe:
3809 if (
OpenCL().checkSubgroupExt(TheCall) ||
3810 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3813 case Builtin::BIget_pipe_num_packets:
3814 case Builtin::BIget_pipe_max_packets:
3815 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3818 case Builtin::BIto_global:
3819 case Builtin::BIto_local:
3820 case Builtin::BIto_private:
3821 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3825 case Builtin::BIenqueue_kernel:
3826 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3829 case Builtin::BIget_kernel_work_group_size:
3830 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3831 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3834 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3835 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3836 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3839 case Builtin::BI__builtin_os_log_format:
3840 Cleanup.setExprNeedsCleanups(
true);
3842 case Builtin::BI__builtin_os_log_format_buffer_size:
3843 if (BuiltinOSLogFormat(TheCall))
3846 case Builtin::BI__builtin_frame_address:
3847 case Builtin::BI__builtin_return_address: {
3856 Result.Val.getInt() != 0)
3858 << ((BuiltinID == Builtin::BI__builtin_return_address)
3859 ?
"__builtin_return_address"
3860 :
"__builtin_frame_address")
3865 case Builtin::BI__builtin_nondeterministic_value: {
3866 if (BuiltinNonDeterministicValue(TheCall))
3873 case Builtin::BI__builtin_elementwise_abs:
3881 case Builtin::BI__builtin_elementwise_acos:
3882 case Builtin::BI__builtin_elementwise_asin:
3883 case Builtin::BI__builtin_elementwise_atan:
3884 case Builtin::BI__builtin_elementwise_ceil:
3885 case Builtin::BI__builtin_elementwise_cos:
3886 case Builtin::BI__builtin_elementwise_cosh:
3887 case Builtin::BI__builtin_elementwise_exp:
3888 case Builtin::BI__builtin_elementwise_exp2:
3889 case Builtin::BI__builtin_elementwise_exp10:
3890 case Builtin::BI__builtin_elementwise_floor:
3891 case Builtin::BI__builtin_elementwise_log:
3892 case Builtin::BI__builtin_elementwise_log2:
3893 case Builtin::BI__builtin_elementwise_log10:
3894 case Builtin::BI__builtin_elementwise_roundeven:
3895 case Builtin::BI__builtin_elementwise_round:
3896 case Builtin::BI__builtin_elementwise_rint:
3897 case Builtin::BI__builtin_elementwise_nearbyint:
3898 case Builtin::BI__builtin_elementwise_sin:
3899 case Builtin::BI__builtin_elementwise_sinh:
3900 case Builtin::BI__builtin_elementwise_sqrt:
3901 case Builtin::BI__builtin_elementwise_tan:
3902 case Builtin::BI__builtin_elementwise_tanh:
3903 case Builtin::BI__builtin_elementwise_trunc:
3904 case Builtin::BI__builtin_elementwise_canonicalize:
3909 case Builtin::BI__builtin_elementwise_fma:
3914 case Builtin::BI__builtin_elementwise_ldexp: {
3936 const auto *Vec0 = TyA->
getAs<VectorType>();
3937 const auto *Vec1 = TyExp->
getAs<VectorType>();
3938 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3940 if (Arg0Length != Arg1Length) {
3942 diag::err_typecheck_vector_lengths_not_equal)
3956 case Builtin::BI__builtin_elementwise_minnum:
3957 case Builtin::BI__builtin_elementwise_maxnum:
3958 case Builtin::BI__builtin_elementwise_minimum:
3959 case Builtin::BI__builtin_elementwise_maximum:
3960 case Builtin::BI__builtin_elementwise_minimumnum:
3961 case Builtin::BI__builtin_elementwise_maximumnum:
3962 case Builtin::BI__builtin_elementwise_atan2:
3963 case Builtin::BI__builtin_elementwise_fmod:
3964 case Builtin::BI__builtin_elementwise_pow:
3965 if (BuiltinElementwiseMath(TheCall,
3971 case Builtin::BI__builtin_elementwise_add_sat:
3972 case Builtin::BI__builtin_elementwise_sub_sat:
3973 case Builtin::BI__builtin_elementwise_clmul:
3974 case Builtin::BI__builtin_elementwise_pext:
3975 case Builtin::BI__builtin_elementwise_pdep:
3976 if (BuiltinElementwiseMath(TheCall,
3980 case Builtin::BI__builtin_elementwise_fshl:
3981 case Builtin::BI__builtin_elementwise_fshr:
3986 case Builtin::BI__builtin_elementwise_min:
3987 case Builtin::BI__builtin_elementwise_max: {
3988 if (BuiltinElementwiseMath(TheCall))
3990 Expr *Arg0 = TheCall->
getArg(0);
3991 Expr *Arg1 = TheCall->
getArg(1);
3992 QualType Ty0 = Arg0->
getType();
3993 QualType Ty1 = Arg1->
getType();
3994 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3995 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3998 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3999 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
4000 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
4003 case Builtin::BI__builtin_elementwise_popcount:
4004 case Builtin::BI__builtin_elementwise_bitreverse:
4009 case Builtin::BI__builtin_elementwise_copysign: {
4018 QualType MagnitudeTy = Magnitude.
get()->
getType();
4031 diag::err_typecheck_call_different_arg_types)
4032 << MagnitudeTy << SignTy;
4040 case Builtin::BI__builtin_elementwise_clzg:
4041 case Builtin::BI__builtin_elementwise_ctzg:
4049 }
else if (BuiltinElementwiseMath(
4053 case Builtin::BI__builtin_reduce_max:
4054 case Builtin::BI__builtin_reduce_min: {
4055 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4058 const Expr *Arg = TheCall->
getArg(0);
4063 ElTy = TyA->getElementType();
4067 if (ElTy.isNull()) {
4077 case Builtin::BI__builtin_reduce_maximum:
4078 case Builtin::BI__builtin_reduce_minimum: {
4079 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4082 const Expr *Arg = TheCall->
getArg(0);
4087 ElTy = TyA->getElementType();
4091 if (ElTy.isNull() || !ElTy->isFloatingType()) {
4104 case Builtin::BI__builtin_reduce_add:
4105 case Builtin::BI__builtin_reduce_mul:
4106 case Builtin::BI__builtin_reduce_xor:
4107 case Builtin::BI__builtin_reduce_or:
4108 case Builtin::BI__builtin_reduce_and: {
4109 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4112 const Expr *Arg = TheCall->
getArg(0);
4126 case Builtin::BI__builtin_reduce_assoc_fadd:
4127 case Builtin::BI__builtin_reduce_in_order_fadd: {
4129 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
4154 diag::err_builtin_invalid_arg_type)
4166 case Builtin::BI__builtin_matrix_transpose:
4167 return BuiltinMatrixTranspose(TheCall, TheCallResult);
4169 case Builtin::BI__builtin_matrix_column_major_load:
4170 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
4172 case Builtin::BI__builtin_matrix_column_major_store:
4173 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
4175 case Builtin::BI__builtin_verbose_trap:
4180 case Builtin::BI__builtin_get_device_side_mangled_name: {
4181 auto Check = [](CallExpr *TheCall) {
4187 auto *D = DRE->getDecl();
4190 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
4191 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
4193 if (!Check(TheCall)) {
4195 diag::err_hip_invalid_args_builtin_mangled_name);
4200 case Builtin::BI__builtin_bswapg:
4204 case Builtin::BI__builtin_bitreverseg:
4208 case Builtin::BI__builtin_popcountg:
4212 case Builtin::BI__builtin_clzg:
4213 case Builtin::BI__builtin_ctzg:
4218 case Builtin::BI__builtin_stdc_rotate_left:
4219 case Builtin::BI__builtin_stdc_rotate_right:
4224 case Builtin::BI__builtin_stdc_memreverse8:
4225 case Builtin::BIstdc_memreverse8:
4226 case Builtin::BIstdc_memreverse8u8:
4227 case Builtin::BIstdc_memreverse8u16:
4228 case Builtin::BIstdc_memreverse8u32:
4229 case Builtin::BIstdc_memreverse8u64:
4230 if (
Context.getTargetInfo().getCharWidth() != 8) {
4237 case Builtin::BI__builtin_stdc_bit_floor:
4238 case Builtin::BI__builtin_stdc_bit_ceil:
4242 case Builtin::BI__builtin_stdc_has_single_bit:
4246 case Builtin::BI__builtin_stdc_leading_zeros:
4247 case Builtin::BI__builtin_stdc_leading_ones:
4248 case Builtin::BI__builtin_stdc_trailing_zeros:
4249 case Builtin::BI__builtin_stdc_trailing_ones:
4250 case Builtin::BI__builtin_stdc_first_leading_zero:
4251 case Builtin::BI__builtin_stdc_first_leading_one:
4252 case Builtin::BI__builtin_stdc_first_trailing_zero:
4253 case Builtin::BI__builtin_stdc_first_trailing_one:
4254 case Builtin::BI__builtin_stdc_count_zeros:
4255 case Builtin::BI__builtin_stdc_count_ones:
4256 case Builtin::BI__builtin_stdc_bit_width:
4261 case Builtin::BI__builtin_allow_runtime_check: {
4262 Expr *Arg = TheCall->
getArg(0);
4272 case Builtin::BI__builtin_allow_sanitize_check: {
4276 Expr *Arg = TheCall->
getArg(0);
4278 const StringLiteral *SanitizerName =
4280 if (!SanitizerName) {
4286 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4287 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4288 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4292 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4298 case Builtin::BI__builtin_counted_by_ref:
4299 if (BuiltinCountedByRef(TheCall))
4309 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4310 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4311 assert(
Context.getAuxTargetInfo() &&
4312 "Aux Target Builtin, but not an aux target?");
4314 if (CheckTSBuiltinFunctionCall(
4316 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4319 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4325 return TheCallResult;
4340 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4344 diag::err_argument_not_contiguous_bit_field)
4351 bool IsVariadic =
false;
4354 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4355 IsVariadic = BD->isVariadic();
4356 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4357 IsVariadic = OMD->isVariadic();
4364 bool HasImplicitThisParam,
bool IsVariadic,
4368 else if (IsVariadic)
4378 if (HasImplicitThisParam) {
4410 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4411 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4412 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4413 Expr = ILE->getInit(0);
4423 const Expr *ArgExpr,
4427 S.
PDiag(diag::warn_null_arg)
4433 if (
auto nullability =
type->getNullability())
4444 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4450 llvm::SmallBitVector NonNullArgs;
4456 for (
const auto *Arg : Args)
4463 unsigned IdxAST = Idx.getASTIndex();
4464 if (IdxAST >= Args.size())
4466 if (NonNullArgs.empty())
4467 NonNullArgs.resize(Args.size());
4468 NonNullArgs.set(IdxAST);
4477 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4482 unsigned ParamIndex = 0;
4484 I != E; ++I, ++ParamIndex) {
4487 if (NonNullArgs.empty())
4488 NonNullArgs.resize(Args.size());
4490 NonNullArgs.set(ParamIndex);
4497 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4502 type = blockType->getPointeeType();
4516 if (NonNullArgs.empty())
4517 NonNullArgs.resize(Args.size());
4519 NonNullArgs.set(Index);
4528 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4529 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4530 if (NonNullArgs[ArgIndex])
4536 StringRef ParamName,
QualType ArgTy,
4559 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4560 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4564 if (ArgAlign < ParamAlign)
4565 Diag(Loc, diag::warn_param_mismatched_alignment)
4567 << ParamName << (FDecl !=
nullptr) << FDecl;
4571 const Expr *ThisArg,
4573 if (!FD || Args.empty())
4575 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4576 if (Idx == LifetimeCaptureByAttr::Global ||
4577 Idx == LifetimeCaptureByAttr::Unknown)
4579 if (IsMemberFunction && Idx == 0)
4581 return Args[Idx - IsMemberFunction];
4583 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4588 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4589 for (
int CapturingParamIdx :
Attr->params()) {
4590 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4594 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4597 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4604 for (
const auto *A :
4606 HandleCaptureByAttr(A, I + IsMemberFunction);
4608 if (IsMemberFunction) {
4616 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4626 llvm::any_of(Args, [](
const Expr *E) {
4627 return E && E->isInstantiationDependent();
4632 llvm::SmallBitVector CheckedVarArgs;
4634 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4636 CheckedVarArgs.resize(Args.size());
4637 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4642 CheckedVarArgs.resize(Args.size());
4643 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4650 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4654 : isa_and_nonnull<FunctionDecl>(FDecl)
4656 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4660 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4662 if (
const Expr *Arg = Args[ArgIdx]) {
4663 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4670 if (FDecl || Proto) {
4675 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4676 CheckArgumentWithTypeTag(I, Args, Loc);
4682 if (!Proto && FDecl) {
4684 if (isa_and_nonnull<FunctionProtoType>(FT))
4690 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4692 bool IsScalableArg =
false;
4693 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4695 if (
const Expr *Arg = Args[ArgIdx]) {
4699 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4707 IsScalableArg =
true;
4709 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4718 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4719 llvm::StringMap<bool> CallerFeatureMap;
4720 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4721 if (!CallerFeatureMap.contains(
"sme"))
4722 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4723 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4724 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4733 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4735 (IsScalableArg || IsScalableRet)) {
4736 bool IsCalleeStreaming =
4738 bool IsCalleeStreamingCompatible =
4742 if (!IsCalleeStreamingCompatible &&
4746 unsigned VL = LO.VScaleMin * 128;
4747 unsigned SVL = LO.VScaleStreamingMin * 128;
4748 bool IsVLMismatch = VL && SVL && VL != SVL;
4750 auto EmitDiag = [&](
bool IsArg) {
4754 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4755 << IsArg << IsCalleeStreaming << SVL << VL;
4758 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4759 << IsArg << SVL << VL;
4761 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4778 bool CallerHasZAState =
false;
4779 bool CallerHasZT0State =
false;
4781 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4783 CallerHasZAState =
true;
4785 CallerHasZT0State =
true;
4789 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4791 CallerHasZT0State |=
4793 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4799 Diag(Loc, diag::err_sme_za_call_no_za_state);
4802 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4806 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4807 Diag(Loc, diag::note_sme_use_preserves_za);
4812 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4813 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4814 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4815 if (!Arg->isValueDependent()) {
4817 if (Arg->EvaluateAsInt(Align,
Context)) {
4818 const llvm::APSInt &I = Align.
Val.
getInt();
4819 if (!I.isPowerOf2())
4820 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4821 << Arg->getSourceRange();
4824 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4833 << diag::OffloadLang::SYCL;
4841 AutoT->getTypeConstraintConcept().getAsTemplateDecl()) {
4856 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4857 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4859 checkCall(FDecl, Proto,
nullptr, Args,
true,
4868 IsMemberOperatorCall;
4874 Expr *ImplicitThis =
nullptr;
4879 ImplicitThis = Args[0];
4882 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4893 ThisType =
Context.getPointerType(ThisType);
4899 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4917 CheckAbsoluteValueFunction(TheCall, FDecl);
4918 CheckMaxUnsignedZero(TheCall, FDecl);
4919 CheckInfNaNFunction(TheCall, FDecl);
4930 case Builtin::BIstrlcpy:
4931 case Builtin::BIstrlcat:
4932 CheckStrlcpycatArguments(TheCall, FnInfo);
4934 case Builtin::BIstrncat:
4935 CheckStrncatArguments(TheCall, FnInfo);
4937 case Builtin::BIfree:
4938 CheckFreeArguments(TheCall);
4941 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4950 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4951 Ty =
V->getType().getNonReferenceType();
4952 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4953 Ty = F->getType().getNonReferenceType();
4990 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4993 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4995 case AtomicExpr::AO__c11_atomic_init:
4996 case AtomicExpr::AO__opencl_atomic_init:
4997 llvm_unreachable(
"There is no ordering argument for an init");
4999 case AtomicExpr::AO__c11_atomic_load:
5000 case AtomicExpr::AO__opencl_atomic_load:
5001 case AtomicExpr::AO__hip_atomic_load:
5002 case AtomicExpr::AO__atomic_load_n:
5003 case AtomicExpr::AO__atomic_load:
5004 case AtomicExpr::AO__scoped_atomic_load_n:
5005 case AtomicExpr::AO__scoped_atomic_load:
5006 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
5007 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
5009 case AtomicExpr::AO__c11_atomic_store:
5010 case AtomicExpr::AO__opencl_atomic_store:
5011 case AtomicExpr::AO__hip_atomic_store:
5012 case AtomicExpr::AO__atomic_store:
5013 case AtomicExpr::AO__atomic_store_n:
5014 case AtomicExpr::AO__scoped_atomic_store:
5015 case AtomicExpr::AO__scoped_atomic_store_n:
5016 case AtomicExpr::AO__atomic_clear:
5017 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
5018 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
5019 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
5049#define HIP_ATOMIC_FIXABLE(hip, scoped) \
5050 case AtomicExpr::AO__hip_atomic_##hip: \
5051 OldName = "__hip_atomic_" #hip; \
5052 NewName = "__scoped_atomic_" #scoped; \
5065#undef HIP_ATOMIC_FIXABLE
5066 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5067 OldName =
"__hip_atomic_compare_exchange_weak";
5068 NewName =
"__scoped_atomic_compare_exchange";
5071 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5072 OldName =
"__hip_atomic_compare_exchange_strong";
5073 NewName =
"__scoped_atomic_compare_exchange";
5077 llvm_unreachable(
"unhandled HIP atomic op");
5080 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
5081 << OldName << NewName;
5088 std::optional<llvm::APSInt> ScopeVal =
5093 StringRef ScopeName;
5094 switch (ScopeVal->getZExtValue()) {
5096 ScopeName =
"__MEMORY_SCOPE_SINGLE";
5099 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
5102 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
5105 ScopeName =
"__MEMORY_SCOPE_DEVICE";
5108 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
5111 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
5163 const unsigned NumForm = ClearByte + 1;
5164 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
5165 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
5173 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
5174 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
5175 "need to update code for modified forms");
5176 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
5177 AtomicExpr::AO__atomic_xor_fetch + 1 ==
5178 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
5179 "need to update code for modified C11 atomics");
5180 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
5181 Op <= AtomicExpr::AO__opencl_atomic_store;
5182 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
5183 Op <= AtomicExpr::AO__hip_atomic_store;
5184 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
5185 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
5186 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
5187 Op <= AtomicExpr::AO__c11_atomic_store) ||
5189 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
5190 Op == AtomicExpr::AO__atomic_store_n ||
5191 Op == AtomicExpr::AO__atomic_exchange_n ||
5192 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
5193 Op == AtomicExpr::AO__scoped_atomic_load_n ||
5194 Op == AtomicExpr::AO__scoped_atomic_store_n ||
5195 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
5196 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
5200 enum ArithOpExtraValueType {
5206 unsigned ArithAllows = AOEVT_None;
5209 case AtomicExpr::AO__c11_atomic_init:
5210 case AtomicExpr::AO__opencl_atomic_init:
5214 case AtomicExpr::AO__c11_atomic_load:
5215 case AtomicExpr::AO__opencl_atomic_load:
5216 case AtomicExpr::AO__hip_atomic_load:
5217 case AtomicExpr::AO__atomic_load_n:
5218 case AtomicExpr::AO__scoped_atomic_load_n:
5219 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5223 case AtomicExpr::AO__atomic_load:
5224 case AtomicExpr::AO__scoped_atomic_load:
5225 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5229 case AtomicExpr::AO__c11_atomic_store:
5230 case AtomicExpr::AO__opencl_atomic_store:
5231 case AtomicExpr::AO__hip_atomic_store:
5232 case AtomicExpr::AO__atomic_store:
5233 case AtomicExpr::AO__atomic_store_n:
5234 case AtomicExpr::AO__scoped_atomic_store:
5235 case AtomicExpr::AO__scoped_atomic_store_n:
5236 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5239 case AtomicExpr::AO__atomic_fetch_add:
5240 case AtomicExpr::AO__atomic_fetch_sub:
5241 case AtomicExpr::AO__atomic_add_fetch:
5242 case AtomicExpr::AO__atomic_sub_fetch:
5243 case AtomicExpr::AO__scoped_atomic_fetch_add:
5244 case AtomicExpr::AO__scoped_atomic_fetch_sub:
5245 case AtomicExpr::AO__scoped_atomic_add_fetch:
5246 case AtomicExpr::AO__scoped_atomic_sub_fetch:
5247 case AtomicExpr::AO__c11_atomic_fetch_add:
5248 case AtomicExpr::AO__c11_atomic_fetch_sub:
5249 case AtomicExpr::AO__opencl_atomic_fetch_add:
5250 case AtomicExpr::AO__opencl_atomic_fetch_sub:
5251 case AtomicExpr::AO__hip_atomic_fetch_add:
5252 case AtomicExpr::AO__hip_atomic_fetch_sub:
5253 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5256 case AtomicExpr::AO__atomic_fetch_fminimum:
5257 case AtomicExpr::AO__atomic_fetch_fmaximum:
5258 case AtomicExpr::AO__atomic_fetch_fminimum_num:
5259 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
5260 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
5261 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
5262 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
5263 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
5264 ArithAllows = AOEVT_FP;
5267 case AtomicExpr::AO__atomic_fetch_max:
5268 case AtomicExpr::AO__atomic_fetch_min:
5269 case AtomicExpr::AO__atomic_max_fetch:
5270 case AtomicExpr::AO__atomic_min_fetch:
5271 case AtomicExpr::AO__scoped_atomic_fetch_max:
5272 case AtomicExpr::AO__scoped_atomic_fetch_min:
5273 case AtomicExpr::AO__scoped_atomic_max_fetch:
5274 case AtomicExpr::AO__scoped_atomic_min_fetch:
5275 case AtomicExpr::AO__c11_atomic_fetch_max:
5276 case AtomicExpr::AO__c11_atomic_fetch_min:
5277 case AtomicExpr::AO__opencl_atomic_fetch_max:
5278 case AtomicExpr::AO__opencl_atomic_fetch_min:
5279 case AtomicExpr::AO__hip_atomic_fetch_max:
5280 case AtomicExpr::AO__hip_atomic_fetch_min:
5281 ArithAllows = AOEVT_Int | AOEVT_FP;
5284 case AtomicExpr::AO__c11_atomic_fetch_and:
5285 case AtomicExpr::AO__c11_atomic_fetch_or:
5286 case AtomicExpr::AO__c11_atomic_fetch_xor:
5287 case AtomicExpr::AO__hip_atomic_fetch_and:
5288 case AtomicExpr::AO__hip_atomic_fetch_or:
5289 case AtomicExpr::AO__hip_atomic_fetch_xor:
5290 case AtomicExpr::AO__c11_atomic_fetch_nand:
5291 case AtomicExpr::AO__opencl_atomic_fetch_and:
5292 case AtomicExpr::AO__opencl_atomic_fetch_or:
5293 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5294 case AtomicExpr::AO__atomic_fetch_and:
5295 case AtomicExpr::AO__atomic_fetch_or:
5296 case AtomicExpr::AO__atomic_fetch_xor:
5297 case AtomicExpr::AO__atomic_fetch_nand:
5298 case AtomicExpr::AO__atomic_and_fetch:
5299 case AtomicExpr::AO__atomic_or_fetch:
5300 case AtomicExpr::AO__atomic_xor_fetch:
5301 case AtomicExpr::AO__atomic_nand_fetch:
5302 case AtomicExpr::AO__atomic_fetch_uinc:
5303 case AtomicExpr::AO__atomic_fetch_udec:
5304 case AtomicExpr::AO__scoped_atomic_fetch_and:
5305 case AtomicExpr::AO__scoped_atomic_fetch_or:
5306 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5307 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5308 case AtomicExpr::AO__scoped_atomic_and_fetch:
5309 case AtomicExpr::AO__scoped_atomic_or_fetch:
5310 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5311 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5312 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5313 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5317 case AtomicExpr::AO__c11_atomic_exchange:
5318 case AtomicExpr::AO__hip_atomic_exchange:
5319 case AtomicExpr::AO__opencl_atomic_exchange:
5320 case AtomicExpr::AO__atomic_exchange_n:
5321 case AtomicExpr::AO__scoped_atomic_exchange_n:
5322 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5326 case AtomicExpr::AO__atomic_exchange:
5327 case AtomicExpr::AO__scoped_atomic_exchange:
5328 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5332 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5333 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5334 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5335 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5336 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5337 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5341 case AtomicExpr::AO__atomic_compare_exchange:
5342 case AtomicExpr::AO__atomic_compare_exchange_n:
5343 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5344 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5345 ArithAllows = AOEVT_Pointer;
5349 case AtomicExpr::AO__atomic_test_and_set:
5350 Form = TestAndSetByte;
5353 case AtomicExpr::AO__atomic_clear:
5358 unsigned AdjustedNumArgs = NumArgs[Form];
5359 if ((IsOpenCL || IsHIP || IsScoped) &&
5360 Op != AtomicExpr::AO__opencl_atomic_init)
5363 if (Args.size() < AdjustedNumArgs) {
5364 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5365 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5368 }
else if (Args.size() > AdjustedNumArgs) {
5369 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5370 diag::err_typecheck_call_too_many_args)
5371 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5377 Expr *Ptr = Args[0];
5382 Ptr = ConvertedPtr.
get();
5385 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5386 << Ptr->getType() << 0 << Ptr->getSourceRange();
5395 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5396 << Ptr->getType() << Ptr->getSourceRange();
5401 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5403 << Ptr->getSourceRange();
5407 }
else if (Form != Load && Form != LoadCopy) {
5409 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5410 << Ptr->getType() << Ptr->getSourceRange();
5415 if (Form != TestAndSetByte && Form != ClearByte) {
5418 diag::err_incomplete_type))
5421 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5422 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5423 << Ptr->getType() << 1 << Ptr->getSourceRange();
5432 pointerType->getPointeeType().getCVRQualifiers());
5442 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5443 << 0 << Ptr->getType() << Ptr->getSourceRange();
5452 auto IsAllowedValueType = [&](
QualType ValType,
5453 unsigned AllowedType) ->
bool {
5454 bool IsX87LongDouble =
5456 &
Context.getTargetInfo().getLongDoubleFormat() ==
5457 &llvm::APFloat::x87DoubleExtended();
5461 return (AllowedType & AOEVT_Int) || AllowedType != AOEVT_FP;
5463 return AllowedType & AOEVT_Pointer;
5467 if (IsX87LongDouble)
5471 if (!IsAllowedValueType(ValType, ArithAllows)) {
5473 ArithAllows == AOEVT_FP
5474 ? diag::err_atomic_op_needs_atomic_fp
5475 : (ArithAllows & AOEVT_FP
5476 ? (ArithAllows & AOEVT_Pointer
5477 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5478 : diag::err_atomic_op_needs_atomic_int_or_fp)
5479 : (ArithAllows & AOEVT_Pointer
5480 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5481 : diag::err_atomic_op_needs_atomic_int));
5483 << IsC11 << Ptr->getType() << Ptr->getSourceRange();
5488 diag::err_incomplete_type)) {
5499 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5500 << Ptr->getType() << Ptr->getSourceRange();
5515 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5516 << ValType << Ptr->getSourceRange();
5527 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5530 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5536 bool IsPassedByAddress =
false;
5537 if (!IsC11 && !IsHIP && !IsN) {
5538 ByValType = Ptr->getType();
5539 IsPassedByAddress =
true;
5544 APIOrderedArgs.push_back(Args[0]);
5548 APIOrderedArgs.push_back(Args[1]);
5554 APIOrderedArgs.push_back(Args[2]);
5555 APIOrderedArgs.push_back(Args[1]);
5558 APIOrderedArgs.push_back(Args[2]);
5559 APIOrderedArgs.push_back(Args[3]);
5560 APIOrderedArgs.push_back(Args[1]);
5563 APIOrderedArgs.push_back(Args[2]);
5564 APIOrderedArgs.push_back(Args[4]);
5565 APIOrderedArgs.push_back(Args[1]);
5566 APIOrderedArgs.push_back(Args[3]);
5569 APIOrderedArgs.push_back(Args[2]);
5570 APIOrderedArgs.push_back(Args[4]);
5571 APIOrderedArgs.push_back(Args[5]);
5572 APIOrderedArgs.push_back(Args[1]);
5573 APIOrderedArgs.push_back(Args[3]);
5575 case TestAndSetByte:
5577 APIOrderedArgs.push_back(Args[1]);
5581 APIOrderedArgs.append(Args.begin(), Args.end());
5588 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5590 if (i < NumVals[Form] + 1) {
5603 assert(Form != Load);
5605 Ty =
Context.getPointerDiffType();
5608 else if (Form ==
Copy || Form == Xchg) {
5609 if (IsPassedByAddress) {
5616 Expr *ValArg = APIOrderedArgs[i];
5623 AS = PtrTy->getPointeeType().getAddressSpace();
5632 if (IsPassedByAddress)
5652 APIOrderedArgs[i] = Arg.
get();
5657 SubExprs.push_back(Ptr);
5661 SubExprs.push_back(APIOrderedArgs[1]);
5664 case TestAndSetByte:
5666 SubExprs.push_back(APIOrderedArgs[1]);
5672 SubExprs.push_back(APIOrderedArgs[2]);
5673 SubExprs.push_back(APIOrderedArgs[1]);
5677 SubExprs.push_back(APIOrderedArgs[3]);
5678 SubExprs.push_back(APIOrderedArgs[1]);
5679 SubExprs.push_back(APIOrderedArgs[2]);
5682 SubExprs.push_back(APIOrderedArgs[3]);
5683 SubExprs.push_back(APIOrderedArgs[1]);
5684 SubExprs.push_back(APIOrderedArgs[4]);
5685 SubExprs.push_back(APIOrderedArgs[2]);
5688 SubExprs.push_back(APIOrderedArgs[4]);
5689 SubExprs.push_back(APIOrderedArgs[1]);
5690 SubExprs.push_back(APIOrderedArgs[5]);
5691 SubExprs.push_back(APIOrderedArgs[2]);
5692 SubExprs.push_back(APIOrderedArgs[3]);
5697 if (SubExprs.size() >= 2 && Form !=
Init) {
5698 std::optional<llvm::APSInt>
Success =
5699 SubExprs[1]->getIntegerConstantExpr(
Context);
5701 Diag(SubExprs[1]->getBeginLoc(),
5702 diag::warn_atomic_op_has_invalid_memory_order)
5703 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5704 << SubExprs[1]->getSourceRange();
5706 if (SubExprs.size() >= 5) {
5707 if (std::optional<llvm::APSInt>
Failure =
5708 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5709 if (!llvm::is_contained(
5710 {llvm::AtomicOrderingCABI::relaxed,
5711 llvm::AtomicOrderingCABI::consume,
5712 llvm::AtomicOrderingCABI::acquire,
5713 llvm::AtomicOrderingCABI::seq_cst},
5714 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5715 Diag(SubExprs[3]->getBeginLoc(),
5716 diag::warn_atomic_op_has_invalid_memory_order)
5717 << 2 << SubExprs[3]->getSourceRange();
5724 auto *
Scope = Args[Args.size() - 1];
5725 if (std::optional<llvm::APSInt>
Result =
5727 if (!ScopeModel->isValid(
Result->getZExtValue()))
5728 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5729 <<
Scope->getSourceRange();
5731 SubExprs.push_back(
Scope);
5740 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5741 Op == AtomicExpr::AO__c11_atomic_store ||
5742 Op == AtomicExpr::AO__opencl_atomic_load ||
5743 Op == AtomicExpr::AO__hip_atomic_load ||
5744 Op == AtomicExpr::AO__opencl_atomic_store ||
5745 Op == AtomicExpr::AO__hip_atomic_store) &&
5746 Context.AtomicUsesUnsupportedLibcall(AE))
5748 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5749 Op == AtomicExpr::AO__opencl_atomic_load ||
5750 Op == AtomicExpr::AO__hip_atomic_load)
5755 Diag(Ptr->getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5771 assert(Fn &&
"builtin call without direct callee!");
5787 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5794 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5796 <<
Callee->getSourceRange();
5805 Expr *FirstArg = TheCall->
getArg(0);
5809 FirstArg = FirstArgResult.
get();
5810 TheCall->
setArg(0, FirstArg);
5822 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5829 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5860 QualType ResultType = ValType;
5865#define BUILTIN_ROW(x) \
5866 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5867 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5869 static const unsigned BuiltinIndices[][5] = {
5894 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5895 case 1: SizeIndex = 0;
break;
5896 case 2: SizeIndex = 1;
break;
5897 case 4: SizeIndex = 2;
break;
5898 case 8: SizeIndex = 3;
break;
5899 case 16: SizeIndex = 4;
break;
5911 unsigned BuiltinIndex, NumFixed = 1;
5912 bool WarnAboutSemanticsChange =
false;
5913 switch (BuiltinID) {
5914 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5915 case Builtin::BI__sync_fetch_and_add:
5916 case Builtin::BI__sync_fetch_and_add_1:
5917 case Builtin::BI__sync_fetch_and_add_2:
5918 case Builtin::BI__sync_fetch_and_add_4:
5919 case Builtin::BI__sync_fetch_and_add_8:
5920 case Builtin::BI__sync_fetch_and_add_16:
5924 case Builtin::BI__sync_fetch_and_sub:
5925 case Builtin::BI__sync_fetch_and_sub_1:
5926 case Builtin::BI__sync_fetch_and_sub_2:
5927 case Builtin::BI__sync_fetch_and_sub_4:
5928 case Builtin::BI__sync_fetch_and_sub_8:
5929 case Builtin::BI__sync_fetch_and_sub_16:
5933 case Builtin::BI__sync_fetch_and_or:
5934 case Builtin::BI__sync_fetch_and_or_1:
5935 case Builtin::BI__sync_fetch_and_or_2:
5936 case Builtin::BI__sync_fetch_and_or_4:
5937 case Builtin::BI__sync_fetch_and_or_8:
5938 case Builtin::BI__sync_fetch_and_or_16:
5942 case Builtin::BI__sync_fetch_and_and:
5943 case Builtin::BI__sync_fetch_and_and_1:
5944 case Builtin::BI__sync_fetch_and_and_2:
5945 case Builtin::BI__sync_fetch_and_and_4:
5946 case Builtin::BI__sync_fetch_and_and_8:
5947 case Builtin::BI__sync_fetch_and_and_16:
5951 case Builtin::BI__sync_fetch_and_xor:
5952 case Builtin::BI__sync_fetch_and_xor_1:
5953 case Builtin::BI__sync_fetch_and_xor_2:
5954 case Builtin::BI__sync_fetch_and_xor_4:
5955 case Builtin::BI__sync_fetch_and_xor_8:
5956 case Builtin::BI__sync_fetch_and_xor_16:
5960 case Builtin::BI__sync_fetch_and_nand:
5961 case Builtin::BI__sync_fetch_and_nand_1:
5962 case Builtin::BI__sync_fetch_and_nand_2:
5963 case Builtin::BI__sync_fetch_and_nand_4:
5964 case Builtin::BI__sync_fetch_and_nand_8:
5965 case Builtin::BI__sync_fetch_and_nand_16:
5967 WarnAboutSemanticsChange =
true;
5970 case Builtin::BI__sync_add_and_fetch:
5971 case Builtin::BI__sync_add_and_fetch_1:
5972 case Builtin::BI__sync_add_and_fetch_2:
5973 case Builtin::BI__sync_add_and_fetch_4:
5974 case Builtin::BI__sync_add_and_fetch_8:
5975 case Builtin::BI__sync_add_and_fetch_16:
5979 case Builtin::BI__sync_sub_and_fetch:
5980 case Builtin::BI__sync_sub_and_fetch_1:
5981 case Builtin::BI__sync_sub_and_fetch_2:
5982 case Builtin::BI__sync_sub_and_fetch_4:
5983 case Builtin::BI__sync_sub_and_fetch_8:
5984 case Builtin::BI__sync_sub_and_fetch_16:
5988 case Builtin::BI__sync_and_and_fetch:
5989 case Builtin::BI__sync_and_and_fetch_1:
5990 case Builtin::BI__sync_and_and_fetch_2:
5991 case Builtin::BI__sync_and_and_fetch_4:
5992 case Builtin::BI__sync_and_and_fetch_8:
5993 case Builtin::BI__sync_and_and_fetch_16:
5997 case Builtin::BI__sync_or_and_fetch:
5998 case Builtin::BI__sync_or_and_fetch_1:
5999 case Builtin::BI__sync_or_and_fetch_2:
6000 case Builtin::BI__sync_or_and_fetch_4:
6001 case Builtin::BI__sync_or_and_fetch_8:
6002 case Builtin::BI__sync_or_and_fetch_16:
6006 case Builtin::BI__sync_xor_and_fetch:
6007 case Builtin::BI__sync_xor_and_fetch_1:
6008 case Builtin::BI__sync_xor_and_fetch_2:
6009 case Builtin::BI__sync_xor_and_fetch_4:
6010 case Builtin::BI__sync_xor_and_fetch_8:
6011 case Builtin::BI__sync_xor_and_fetch_16:
6015 case Builtin::BI__sync_nand_and_fetch:
6016 case Builtin::BI__sync_nand_and_fetch_1:
6017 case Builtin::BI__sync_nand_and_fetch_2:
6018 case Builtin::BI__sync_nand_and_fetch_4:
6019 case Builtin::BI__sync_nand_and_fetch_8:
6020 case Builtin::BI__sync_nand_and_fetch_16:
6022 WarnAboutSemanticsChange =
true;
6025 case Builtin::BI__sync_val_compare_and_swap:
6026 case Builtin::BI__sync_val_compare_and_swap_1:
6027 case Builtin::BI__sync_val_compare_and_swap_2:
6028 case Builtin::BI__sync_val_compare_and_swap_4:
6029 case Builtin::BI__sync_val_compare_and_swap_8:
6030 case Builtin::BI__sync_val_compare_and_swap_16:
6035 case Builtin::BI__sync_bool_compare_and_swap:
6036 case Builtin::BI__sync_bool_compare_and_swap_1:
6037 case Builtin::BI__sync_bool_compare_and_swap_2:
6038 case Builtin::BI__sync_bool_compare_and_swap_4:
6039 case Builtin::BI__sync_bool_compare_and_swap_8:
6040 case Builtin::BI__sync_bool_compare_and_swap_16:
6046 case Builtin::BI__sync_lock_test_and_set:
6047 case Builtin::BI__sync_lock_test_and_set_1:
6048 case Builtin::BI__sync_lock_test_and_set_2:
6049 case Builtin::BI__sync_lock_test_and_set_4:
6050 case Builtin::BI__sync_lock_test_and_set_8:
6051 case Builtin::BI__sync_lock_test_and_set_16:
6055 case Builtin::BI__sync_lock_release:
6056 case Builtin::BI__sync_lock_release_1:
6057 case Builtin::BI__sync_lock_release_2:
6058 case Builtin::BI__sync_lock_release_4:
6059 case Builtin::BI__sync_lock_release_8:
6060 case Builtin::BI__sync_lock_release_16:
6066 case Builtin::BI__sync_swap:
6067 case Builtin::BI__sync_swap_1:
6068 case Builtin::BI__sync_swap_2:
6069 case Builtin::BI__sync_swap_4:
6070 case Builtin::BI__sync_swap_8:
6071 case Builtin::BI__sync_swap_16:
6079 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
6080 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
6081 <<
Callee->getSourceRange();
6085 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
6086 <<
Callee->getSourceRange();
6088 if (WarnAboutSemanticsChange) {
6089 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
6090 <<
Callee->getSourceRange();
6095 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
6096 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
6097 FunctionDecl *NewBuiltinDecl;
6098 if (NewBuiltinID == BuiltinID)
6099 NewBuiltinDecl = FDecl;
6102 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
6105 assert(Res.getFoundDecl());
6106 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
6107 if (!NewBuiltinDecl)
6114 for (
unsigned i = 0; i != NumFixed; ++i) {
6143 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
6145 CK_BuiltinFnToFnPtr);
6156 const auto *BitIntValType = ValType->
getAs<BitIntType>();
6157 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
6158 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
6162 return TheCallResult;
6166 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
6171 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
6172 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
6173 "Unexpected nontemporal load/store builtin!");
6174 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
6175 unsigned numArgs = isStore ? 2 : 1;
6185 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
6191 PointerArg = PointerArgResult.
get();
6192 TheCall->
setArg(numArgs - 1, PointerArg);
6196 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
6209 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
6216 return TheCallResult;
6228 return TheCallResult;
6235 auto *
Literal = dyn_cast<StringLiteral>(Arg);
6237 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
6238 Literal = ObjcLiteral->getString();
6242 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
6249 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
6250 InitializedEntity Entity =
6260 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
6261 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
6262 TT.getArch() == llvm::Triple::aarch64_32);
6263 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
6264 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
6265 if (IsX64 || IsAArch64) {
6272 return S.
Diag(Fn->getBeginLoc(),
6273 diag::err_ms_va_start_used_in_sysv_function);
6280 (!IsWindowsOrUEFI && CC ==
CC_Win64))
6281 return S.
Diag(Fn->getBeginLoc(),
6282 diag::err_va_start_used_in_wrong_abi_function)
6283 << !IsWindowsOrUEFI;
6289 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6297 bool IsVariadic =
false;
6301 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6302 IsVariadic =
Block->isVariadic();
6303 Params =
Block->parameters();
6304 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6307 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6308 IsVariadic = MD->isVariadic();
6310 Params = MD->parameters();
6313 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6317 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6322 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6327 *LastParam = Params.empty() ?
nullptr : Params.back();
6332bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6337 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6361 ParmVarDecl *LastParam;
6372 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6374 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6379 if (std::optional<llvm::APSInt> Val =
6381 Val &&
LangOpts.C23 && *Val == 0 &&
6382 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6383 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6390 SourceLocation ParamLoc;
6391 bool IsCRegister =
false;
6392 bool SecondArgIsLastNonVariadicArgument =
false;
6393 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6394 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6395 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6398 ParamLoc = PV->getLocation();
6404 if (!SecondArgIsLastNonVariadicArgument)
6406 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6407 else if (IsCRegister ||
Type->isReferenceType() ||
6408 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6411 if (!Context.isPromotableIntegerType(Type))
6413 const auto *ED = Type->getAsEnumDecl();
6416 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6418 unsigned Reason = 0;
6419 if (
Type->isReferenceType()) Reason = 1;
6420 else if (IsCRegister) Reason = 2;
6421 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6422 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6429 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6449 if (
Call->getNumArgs() < 3)
6451 diag::err_typecheck_call_too_few_args_at_least)
6452 << 0 << 3 <<
Call->getNumArgs()
6468 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6471 const QualType &ConstCharPtrTy =
6473 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6475 << Arg1->
getType() << ConstCharPtrTy << 1
6478 << 2 << Arg1->
getType() << ConstCharPtrTy;
6480 const QualType SizeTy =
Context.getSizeType();
6485 << Arg2->
getType() << SizeTy << 1
6488 << 3 << Arg2->
getType() << SizeTy;
6493bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6497 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6525 diag::err_typecheck_call_invalid_ordered_compare)
6533bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6534 unsigned BuiltinID) {
6539 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6540 BuiltinID == Builtin::BI__builtin_isinf ||
6541 BuiltinID == Builtin::BI__builtin_isinf_sign))
6545 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6546 BuiltinID == Builtin::BI__builtin_isunordered))
6550 bool IsFPClass = NumArgs == 2;
6553 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6557 for (
unsigned i = 0; i < FPArgNo; ++i) {
6558 Expr *Arg = TheCall->
getArg(i);
6571 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6580 OrigArg = Res.
get();
6582 TheCall->
setArg(FPArgNo, OrigArg);
6584 QualType VectorResultTy;
6585 QualType ElementTy = OrigArg->
getType();
6590 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6596 diag::err_typecheck_call_invalid_unary_fp)
6609 TheCall->
setArg(NumArgs - 1, MaskRes.
get());
6615 if (!VectorResultTy.
isNull())
6616 ResultTy = VectorResultTy;
6625bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6630 for (
unsigned I = 0; I != 2; ++I) {
6631 Expr *Arg = TheCall->
getArg(I);
6641 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6656 Expr *Real = TheCall->
getArg(0);
6657 Expr *Imag = TheCall->
getArg(1);
6660 diag::err_typecheck_call_different_arg_types)
6675 diag::err_typecheck_call_too_few_args_at_least)
6676 << 0 << 2 << NumArgs
6683 unsigned NumElements = 0;
6698 unsigned NumResElements = NumArgs - 2;
6705 if (RHSVecType->getElementType()->isBooleanType() ||
6706 !RHSVecType->getElementType()->isIntegerType()) {
6715 if (RHSVecType->getNumElements() != NumElements)
6717 diag::err_typecheck_vector_lengths_not_equal)
6718 << LHSType << RHSType <<
false
6721 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6723 diag::err_vec_builtin_incompatible_vector)
6728 }
else if (NumElements != NumResElements) {
6731 ?
Context.getExtVectorType(EltType, NumResElements)
6732 :
Context.getVectorType(EltType, NumResElements,
6737 for (
unsigned I = 2; I != NumArgs; ++I) {
6745 diag::err_shufflevector_nonconstant_argument)
6751 else if (
Result->getActiveBits() > 64 ||
6752 Result->getZExtValue() >= NumElements * 2)
6754 diag::err_shufflevector_argument_too_large)
6779 diag::err_convertvector_non_vector)
6782 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6784 <<
"__builtin_convertvector");
6789 if (SrcElts != DstElts)
6791 diag::err_convertvector_incompatible_vector)
6799bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6804 diag::err_typecheck_call_too_many_args_at_most)
6805 << 0 << 3 << NumArgs << 0
6810 for (
unsigned i = 1; i != NumArgs; ++i) {
6820bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6821 if (!
Context.getTargetInfo().checkArithmeticFenceSupported())
6822 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6826 Expr *Arg = TheCall->
getArg(0);
6830 QualType ArgTy = Arg->
getType();
6832 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6842bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6843 Expr *Arg = TheCall->
getArg(0);
6854bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6856 Expr *Arg = TheCall->
getArg(1);
6860 if (
const auto *UE =
6862 if (UE->getKind() == UETT_AlignOf ||
6863 UE->getKind() == UETT_PreferredAlignOf)
6869 if (!
Result.isPowerOf2())
6870 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6877 if (
Result > std::numeric_limits<int32_t>::max())
6885bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6890 Expr *FirstArg = TheCall->
getArg(0);
6896 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6900 TheCall->
setArg(0, FirstArgResult.
get());
6904 Expr *SecondArg = TheCall->
getArg(1);
6912 if (!
Result.isPowerOf2())
6913 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6925 Expr *ThirdArg = TheCall->
getArg(2);
6928 TheCall->
setArg(2, ThirdArg);
6934bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6935 unsigned BuiltinID =
6937 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6940 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6941 if (NumArgs < NumRequiredArgs) {
6942 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6943 << 0 << NumRequiredArgs << NumArgs
6946 if (NumArgs >= NumRequiredArgs + 0x100) {
6948 diag::err_typecheck_call_too_many_args_at_most)
6949 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6960 if (Arg.isInvalid())
6962 TheCall->
setArg(i, Arg.get());
6967 unsigned FormatIdx = i;
6977 unsigned FirstDataArg = i;
6978 while (i < NumArgs) {
6996 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6998 bool Success = CheckFormatArguments(
7001 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
7025 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
7034 int High,
bool RangeIsError) {
7048 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
7056 PDiag(diag::warn_argument_invalid_range)
7099 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
7104 if (
Value.isNegative())
7115 if ((
Value & 0xFF) != 0)
7140 Result.setIsUnsigned(
true);
7145 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
7165 Result.setIsUnsigned(
true);
7173 diag::err_argument_not_shifted_byte_or_xxff)
7177bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
7178 if (!Context.getTargetInfo().hasSjLjLowering())
7179 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
7190 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
7196bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
7197 if (!Context.getTargetInfo().hasSjLjLowering())
7198 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
7203bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
7218 diag::err_builtin_counted_by_ref_invalid_arg)
7223 diag::err_builtin_counted_by_ref_has_side_effects)
7226 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
7228 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
7233 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
7234 if (CountFD->isBitField()) {
7235 Diag(ME->getBeginLoc(),
7236 diag::err_builtin_counted_by_ref_counter_field_is_bitfield)
7238 return Diag(CountFD->getBeginLoc(),
7239 diag::note_counted_by_counter_field)
7240 << CountFD << CountFD->getSourceRange();
7249 QualType MemberTy = ME->getMemberDecl()->getType();
7252 diag::err_builtin_counted_by_ref_invalid_arg)
7256 diag::err_builtin_counted_by_ref_invalid_arg)
7266bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
7268 const CallExpr *CE =
7277 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7282 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7287 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7291 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7295 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7305class UncoveredArgHandler {
7306 enum {
Unknown = -1, AllCovered = -2 };
7308 signed FirstUncoveredArg =
Unknown;
7309 SmallVector<const Expr *, 4> DiagnosticExprs;
7312 UncoveredArgHandler() =
default;
7314 bool hasUncoveredArg()
const {
7315 return (FirstUncoveredArg >= 0);
7318 unsigned getUncoveredArg()
const {
7319 assert(hasUncoveredArg() &&
"no uncovered argument");
7320 return FirstUncoveredArg;
7323 void setAllCovered() {
7326 DiagnosticExprs.clear();
7327 FirstUncoveredArg = AllCovered;
7330 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7331 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7334 if (FirstUncoveredArg == AllCovered)
7339 if (NewFirstUncoveredArg == FirstUncoveredArg)
7340 DiagnosticExprs.push_back(StrExpr);
7341 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7342 DiagnosticExprs.clear();
7343 DiagnosticExprs.push_back(StrExpr);
7344 FirstUncoveredArg = NewFirstUncoveredArg;
7348 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7351enum StringLiteralCheckType {
7353 SLCT_UncheckedLiteral,
7361 bool AddendIsRight) {
7362 unsigned BitWidth = Offset.getBitWidth();
7363 unsigned AddendBitWidth = Addend.getBitWidth();
7365 if (Addend.isUnsigned()) {
7366 Addend = Addend.zext(++AddendBitWidth);
7367 Addend.setIsSigned(
true);
7370 if (AddendBitWidth > BitWidth) {
7371 Offset = Offset.sext(AddendBitWidth);
7372 BitWidth = AddendBitWidth;
7373 }
else if (BitWidth > AddendBitWidth) {
7374 Addend = Addend.sext(BitWidth);
7378 llvm::APSInt ResOffset = Offset;
7379 if (BinOpKind == BO_Add)
7380 ResOffset = Offset.sadd_ov(Addend, Ov);
7382 assert(AddendIsRight && BinOpKind == BO_Sub &&
7383 "operator must be add or sub with addend on the right");
7384 ResOffset = Offset.ssub_ov(Addend, Ov);
7390 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7391 "index (intermediate) result too big");
7392 Offset = Offset.sext(2 * BitWidth);
7393 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7397 Offset = std::move(ResOffset);
7405class FormatStringLiteral {
7406 const StringLiteral *FExpr;
7410 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7411 : FExpr(fexpr), Offset(Offset) {}
7413 const StringLiteral *getFormatString()
const {
return FExpr; }
7415 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7417 unsigned getByteLength()
const {
7418 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7421 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7428 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7429 bool isWide()
const {
return FExpr->
isWide(); }
7430 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7431 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7432 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7433 bool isPascal()
const {
return FExpr->
isPascal(); }
7435 SourceLocation getLocationOfByte(
7436 unsigned ByteNo,
const SourceManager &SM,
const LangOptions &Features,
7437 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7438 unsigned *StartTokenByteOffset =
nullptr)
const {
7440 StartToken, StartTokenByteOffset);
7443 SourceLocation getBeginLoc() const LLVM_READONLY {
7447 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7453 Sema &S,
const FormatStringLiteral *FExpr,
7458 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7459 bool IgnoreStringsWithoutSpecifiers);
7468static StringLiteralCheckType
7474 llvm::SmallBitVector &CheckedVarArgs,
7475 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7476 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7477 bool IgnoreStringsWithoutSpecifiers =
false) {
7479 return SLCT_NotALiteral;
7481 assert(Offset.isSigned() &&
"invalid offset");
7484 return SLCT_NotALiteral;
7493 return SLCT_UncheckedLiteral;
7496 case Stmt::InitListExprClass:
7500 format_idx, firstDataArg,
Type, CallType,
7501 false, CheckedVarArgs,
7502 UncoveredArg, Offset, CallerFormatParamIdx,
7503 IgnoreStringsWithoutSpecifiers);
7505 return SLCT_NotALiteral;
7506 case Stmt::BinaryConditionalOperatorClass:
7507 case Stmt::ConditionalOperatorClass: {
7516 bool CheckLeft =
true, CheckRight =
true;
7519 if (
C->getCond()->EvaluateAsBooleanCondition(
7531 StringLiteralCheckType Left;
7533 Left = SLCT_UncheckedLiteral;
7536 Args, APK, format_idx, firstDataArg,
Type,
7537 CallType, InFunctionCall, CheckedVarArgs,
7538 UncoveredArg, Offset, CallerFormatParamIdx,
7539 IgnoreStringsWithoutSpecifiers);
7540 if (Left == SLCT_NotALiteral || !CheckRight) {
7546 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7547 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7548 UncoveredArg, Offset, CallerFormatParamIdx,
7549 IgnoreStringsWithoutSpecifiers);
7551 return (CheckLeft && Left < Right) ? Left : Right;
7554 case Stmt::ImplicitCastExprClass:
7558 case Stmt::OpaqueValueExprClass:
7563 return SLCT_NotALiteral;
7565 case Stmt::PredefinedExprClass:
7569 return SLCT_UncheckedLiteral;
7571 case Stmt::DeclRefExprClass: {
7577 bool isConstant =
false;
7581 isConstant = AT->getElementType().isConstant(S.
Context);
7583 isConstant =
T.isConstant(S.
Context) &&
7584 PT->getPointeeType().isConstant(S.
Context);
7585 }
else if (
T->isObjCObjectPointerType()) {
7588 isConstant =
T.isConstant(S.
Context);
7592 if (
const Expr *
Init = VD->getAnyInitializer()) {
7595 if (InitList->isStringLiteralInit())
7596 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7599 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7600 firstDataArg,
Type, CallType,
false,
7601 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7652 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7653 if (CallerFormatParamIdx)
7654 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7655 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7656 for (
const auto *PVFormatMatches :
7657 D->specific_attrs<FormatMatchesAttr>()) {
7662 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7666 S.
Diag(Args[format_idx]->getBeginLoc(),
7667 diag::warn_format_string_type_incompatible)
7668 << PVFormatMatches->getType()->getName()
7670 if (!InFunctionCall) {
7671 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7672 diag::note_format_string_defined);
7674 return SLCT_UncheckedLiteral;
7677 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7678 Args, APK, format_idx, firstDataArg,
Type, CallType,
7679 false, CheckedVarArgs, UncoveredArg,
7680 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7684 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7687 PVFormat->getFirstArg(), &CallerFSI))
7689 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7693 S.
Diag(Args[format_idx]->getBeginLoc(),
7694 diag::warn_format_string_type_incompatible)
7695 << PVFormat->getType()->getName()
7697 if (!InFunctionCall) {
7700 return SLCT_UncheckedLiteral;
7713 return SLCT_UncheckedLiteral;
7721 return SLCT_NotALiteral;
7724 case Stmt::CallExprClass:
7725 case Stmt::CXXMemberCallExprClass: {
7729 StringLiteralCheckType CommonResult;
7730 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7731 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7733 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7734 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7735 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7742 return CommonResult;
7744 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7746 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7747 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7750 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7751 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7752 UncoveredArg, Offset, CallerFormatParamIdx,
7753 IgnoreStringsWithoutSpecifiers);
7759 format_idx, firstDataArg,
Type, CallType,
7760 false, CheckedVarArgs,
7761 UncoveredArg, Offset, CallerFormatParamIdx,
7762 IgnoreStringsWithoutSpecifiers);
7763 return SLCT_NotALiteral;
7765 case Stmt::ObjCMessageExprClass: {
7767 if (
const auto *MD = ME->getMethodDecl()) {
7768 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7777 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7779 MD->getSelector().isKeywordSelector(
7780 {
"localizedStringForKey",
"value",
"table"})) {
7781 IgnoreStringsWithoutSpecifiers =
true;
7784 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7786 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7787 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7788 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7792 return SLCT_NotALiteral;
7794 case Stmt::ObjCStringLiteralClass:
7795 case Stmt::StringLiteralClass: {
7804 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7807 return SLCT_NotALiteral;
7809 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7811 format_idx, firstDataArg,
Type, InFunctionCall,
7812 CallType, CheckedVarArgs, UncoveredArg,
7813 IgnoreStringsWithoutSpecifiers);
7814 return SLCT_CheckedLiteral;
7817 return SLCT_NotALiteral;
7819 case Stmt::BinaryOperatorClass: {
7833 if (LIsInt != RIsInt) {
7837 if (BinOpKind == BO_Add) {
7850 return SLCT_NotALiteral;
7852 case Stmt::UnaryOperatorClass: {
7854 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7855 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7857 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7867 return SLCT_NotALiteral;
7871 return SLCT_NotALiteral;
7882 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7883 if (isa_and_nonnull<StringLiteral>(LVE))
7904 return "freebsd_kprintf";
7913 return llvm::StringSwitch<FormatStringType>(Flavor)
7915 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7920 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7936bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7940 llvm::SmallBitVector &CheckedVarArgs) {
7941 FormatStringInfo FSI;
7945 return CheckFormatArguments(
7946 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7951bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7955 llvm::SmallBitVector &CheckedVarArgs) {
7956 FormatStringInfo FSI;
7960 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7961 Format->getFormatString(), FSI.FormatIdx,
7963 CallType, Loc, Range, CheckedVarArgs);
7971 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7984 unsigned CallerArgumentIndexOffset =
7987 unsigned FirstArgumentIndex = -1;
7997 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7998 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
8002 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
8003 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
8005 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
8008 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
8009 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
8012 FirstArgumentIndex =
8013 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
8019 ? (NumCallerParams + CallerArgumentIndexOffset)
8024 if (!ReferenceFormatString)
8030 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
8032 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
8034 std::string
Attr, Fixit;
8035 llvm::raw_string_ostream AttrOS(
Attr);
8037 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
8038 << FirstArgumentIndex <<
")";
8040 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
8042 AttrOS.write_escaped(ReferenceFormatString->
getString());
8046 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
8057 llvm::raw_string_ostream IS(Fixit);
8065 if (LO.C23 || LO.CPlusPlus11)
8066 IS <<
"[[gnu::" <<
Attr <<
"]]";
8067 else if (LO.ObjC || LO.GNUMode)
8068 IS <<
"__attribute__((" <<
Attr <<
"))";
8082 Caller->
addAttr(FormatAttr::CreateImplicit(
8084 FormatStringIndex, FirstArgumentIndex));
8086 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
8088 FormatStringIndex, ReferenceFormatString));
8092 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
8104 unsigned format_idx,
unsigned firstDataArg,
8108 llvm::SmallBitVector &CheckedVarArgs) {
8110 if (format_idx >= Args.size()) {
8111 Diag(Loc, diag::warn_missing_format_string) <<
Range;
8115 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
8129 UncoveredArgHandler UncoveredArg;
8130 std::optional<unsigned> CallerParamIdx;
8132 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
8133 firstDataArg,
Type, CallType,
8134 true, CheckedVarArgs, UncoveredArg,
8135 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
8138 if (UncoveredArg.hasUncoveredArg()) {
8139 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
8140 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
8141 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
8144 if (CT != SLCT_NotALiteral)
8146 return CT == SLCT_CheckedLiteral;
8152 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
8158 this, Args, APK, ReferenceFormatString, format_idx,
8159 firstDataArg,
Type, *CallerParamIdx, Loc))
8169 if (Args.size() == firstDataArg) {
8170 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
8178 Diag(FormatLoc, diag::note_format_security_fixit)
8182 Diag(FormatLoc, diag::note_format_security_fixit)
8187 Diag(FormatLoc, diag::warn_format_nonliteral)
8198 const FormatStringLiteral *FExpr;
8199 const Expr *OrigFormatExpr;
8201 const unsigned FirstDataArg;
8202 const unsigned NumDataArgs;
8205 ArrayRef<const Expr *> Args;
8207 llvm::SmallBitVector CoveredArgs;
8208 bool usesPositionalArgs =
false;
8209 bool atFirstArg =
true;
8210 bool inFunctionCall;
8212 llvm::SmallBitVector &CheckedVarArgs;
8213 UncoveredArgHandler &UncoveredArg;
8216 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
8218 unsigned firstDataArg,
unsigned numDataArgs,
8220 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8222 llvm::SmallBitVector &CheckedVarArgs,
8223 UncoveredArgHandler &UncoveredArg)
8224 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
8225 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
8226 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
8227 inFunctionCall(inFunctionCall), CallType(callType),
8228 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
8229 CoveredArgs.resize(numDataArgs);
8230 CoveredArgs.reset();
8233 bool HasFormatArguments()
const {
8238 void DoneProcessing();
8240 void HandleIncompleteSpecifier(
const char *startSpecifier,
8241 unsigned specifierLen)
override;
8243 void HandleInvalidLengthModifier(
8244 const analyze_format_string::FormatSpecifier &FS,
8245 const analyze_format_string::ConversionSpecifier &CS,
8246 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
8248 void HandleNonStandardLengthModifier(
8249 const analyze_format_string::FormatSpecifier &FS,
8250 const char *startSpecifier,
unsigned specifierLen);
8252 void HandleNonStandardConversionSpecifier(
8253 const analyze_format_string::ConversionSpecifier &CS,
8254 const char *startSpecifier,
unsigned specifierLen);
8256 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
8258 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
8261 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
8263 void HandleNullChar(
const char *nullCharacter)
override;
8265 template <
typename Range>
8267 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
8268 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
8269 bool IsStringLocation, Range StringRange,
8270 ArrayRef<FixItHint> Fixit = {});
8273 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
8274 const char *startSpec,
8275 unsigned specifierLen,
8276 const char *csStart,
unsigned csLen);
8278 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
8279 const char *startSpec,
8280 unsigned specifierLen);
8282 SourceRange getFormatStringRange();
8283 CharSourceRange getSpecifierRange(
const char *startSpecifier,
8284 unsigned specifierLen);
8285 SourceLocation getLocationOfByte(
const char *x);
8287 const Expr *getDataArg(
unsigned i)
const;
8289 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
8290 const analyze_format_string::ConversionSpecifier &CS,
8291 const char *startSpecifier,
unsigned specifierLen,
8294 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
8295 const Expr *E,
const char *startSpecifier,
8296 unsigned specifierLen);
8298 template <
typename Range>
8299 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
8300 bool IsStringLocation, Range StringRange,
8301 ArrayRef<FixItHint> Fixit = {});
8306SourceRange CheckFormatHandler::getFormatStringRange() {
8311CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8312 unsigned specifierLen) {
8314 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8322SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8327void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8328 unsigned specifierLen) {
8329 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8330 getLocationOfByte(startSpecifier),
8332 getSpecifierRange(startSpecifier, specifierLen));
8335bool CheckFormatHandler::CheckUnsupportedType(
8337 const char *StartSpecifier,
unsigned SpecifierLen) {
8341 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8344 getSpecifierRange(StartSpecifier, SpecifierLen));
8348void CheckFormatHandler::HandleInvalidLengthModifier(
8351 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8363 getSpecifierRange(startSpecifier, specifierLen));
8365 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8366 << FixedLM->toString()
8371 if (DiagID == diag::warn_format_nonsensical_length)
8377 getSpecifierRange(startSpecifier, specifierLen), Hint);
8381void CheckFormatHandler::HandleNonStandardLengthModifier(
8383 const char *startSpecifier,
unsigned specifierLen) {
8392 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8396 getSpecifierRange(startSpecifier, specifierLen));
8398 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8399 << FixedLM->toString()
8403 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8407 getSpecifierRange(startSpecifier, specifierLen));
8411void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8413 const char *startSpecifier,
unsigned specifierLen) {
8419 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8423 getSpecifierRange(startSpecifier, specifierLen));
8426 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8427 << FixedCS->toString()
8430 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8434 getSpecifierRange(startSpecifier, specifierLen));
8438void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8440 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8441 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8442 getLocationOfByte(startPos),
8444 getSpecifierRange(startPos, posLen));
8447void CheckFormatHandler::HandleInvalidPosition(
8448 const char *startSpecifier,
unsigned specifierLen,
8451 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8452 EmitFormatDiagnostic(
8453 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8454 getLocationOfByte(startSpecifier),
true,
8455 getSpecifierRange(startSpecifier, specifierLen));
8458void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8462 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8463 getLocationOfByte(startPos),
8465 getSpecifierRange(startPos, posLen));
8468void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8471 EmitFormatDiagnostic(
8472 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8473 getLocationOfByte(nullCharacter),
true,
8474 getFormatStringRange());
8480const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8481 return Args[FirstDataArg + i];
8484void CheckFormatHandler::DoneProcessing() {
8487 if (HasFormatArguments()) {
8490 signed notCoveredArg = CoveredArgs.find_first();
8491 if (notCoveredArg >= 0) {
8492 assert((
unsigned)notCoveredArg < NumDataArgs);
8493 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8495 UncoveredArg.setAllCovered();
8500void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8501 const Expr *ArgExpr) {
8502 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8513 for (
auto E : DiagnosticExprs)
8516 CheckFormatHandler::EmitFormatDiagnostic(
8517 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8521bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8523 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8524 bool keepGoing =
true;
8525 if (argIndex < NumDataArgs) {
8528 CoveredArgs.set(argIndex);
8543 std::string CodePointStr;
8544 if (!llvm::sys::locale::isPrint(*csStart)) {
8545 llvm::UTF32 CodePoint;
8546 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8547 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8548 llvm::ConversionResult
Result =
8549 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8551 if (
Result != llvm::conversionOK) {
8552 unsigned char FirstChar = *csStart;
8553 CodePoint = (llvm::UTF32)FirstChar;
8556 llvm::raw_string_ostream
OS(CodePointStr);
8557 if (CodePoint < 256)
8558 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8559 else if (CodePoint <= 0xFFFF)
8560 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8562 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8566 EmitFormatDiagnostic(
8567 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8568 true, getSpecifierRange(startSpec, specifierLen));
8573void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8574 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8575 EmitFormatDiagnostic(
8576 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8577 true, getSpecifierRange(startSpec, specifierLen));
8580bool CheckFormatHandler::CheckNumArgs(
8583 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8585 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8588 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8589 << (argIndex + 1) << NumDataArgs)
8590 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8591 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8593 getSpecifierRange(startSpecifier, specifierLen));
8597 UncoveredArg.setAllCovered();
8603template <
typename Range>
8606 bool IsStringLocation,
8609 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8610 IsStringLocation, StringRange, FixIt);
8640template <
typename Range>
8641void CheckFormatHandler::EmitFormatDiagnostic(
8642 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8645 if (InFunctionCall) {
8650 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8654 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8655 diag::note_format_string_defined);
8657 Note << StringRange;
8666class CheckPrintfHandler :
public CheckFormatHandler {
8668 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8670 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8672 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8674 llvm::SmallBitVector &CheckedVarArgs,
8675 UncoveredArgHandler &UncoveredArg)
8676 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8677 numDataArgs, beg, APK, Args, formatIdx,
8678 inFunctionCall, CallType, CheckedVarArgs,
8681 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8684 bool allowsObjCArg()
const {
8685 return FSType == FormatStringType::NSString ||
8686 FSType == FormatStringType::OSLog ||
8687 FSType == FormatStringType::OSTrace;
8690 bool HandleInvalidPrintfConversionSpecifier(
8691 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8692 unsigned specifierLen)
override;
8694 void handleInvalidMaskType(StringRef MaskType)
override;
8696 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8697 const char *startSpecifier,
unsigned specifierLen,
8698 const TargetInfo &
Target)
override;
8699 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8700 const char *StartSpecifier,
unsigned SpecifierLen,
8703 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8704 unsigned k,
const char *startSpecifier,
8705 unsigned specifierLen);
8706 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8707 const analyze_printf::OptionalAmount &Amt,
8708 unsigned type,
const char *startSpecifier,
8709 unsigned specifierLen);
8710 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8711 const analyze_printf::OptionalFlag &flag,
8712 const char *startSpecifier,
unsigned specifierLen);
8713 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8714 const analyze_printf::OptionalFlag &ignoredFlag,
8715 const analyze_printf::OptionalFlag &flag,
8716 const char *startSpecifier,
unsigned specifierLen);
8717 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8719 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8720 unsigned flagLen)
override;
8722 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8723 unsigned flagLen)
override;
8726 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8727 const char *flagsEnd,
8728 const char *conversionPosition)
override;
8733class EquatableFormatArgument {
8735 enum SpecifierSensitivity :
unsigned {
8742 enum FormatArgumentRole :
unsigned {
8750 analyze_format_string::ArgType ArgType;
8751 analyze_format_string::LengthModifier LengthMod;
8752 StringRef SpecifierLetter;
8753 CharSourceRange
Range;
8754 SourceLocation ElementLoc;
8755 FormatArgumentRole
Role : 2;
8756 SpecifierSensitivity Sensitivity : 2;
8757 unsigned Position : 14;
8758 unsigned ModifierFor : 14;
8760 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8761 bool InFunctionCall)
const;
8764 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8765 analyze_format_string::LengthModifier LengthMod,
8766 StringRef SpecifierLetter,
8767 analyze_format_string::ArgType ArgType,
8768 FormatArgumentRole
Role,
8769 SpecifierSensitivity Sensitivity,
unsigned Position,
8770 unsigned ModifierFor)
8771 : ArgType(ArgType), LengthMod(LengthMod),
8772 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8773 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8774 ModifierFor(ModifierFor) {}
8776 unsigned getPosition()
const {
return Position; }
8777 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8779 analyze_format_string::LengthModifier getLengthModifier()
const {
8782 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8784 std::string buildFormatSpecifier()
const {
8786 llvm::raw_string_ostream(result)
8787 << getLengthModifier().
toString() << SpecifierLetter;
8791 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8792 const Expr *FmtExpr,
bool InFunctionCall)
const;
8796class DecomposePrintfHandler :
public CheckPrintfHandler {
8797 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8800 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8801 const Expr *origFormatExpr,
8803 unsigned numDataArgs,
bool isObjC,
const char *beg,
8805 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8807 llvm::SmallBitVector &CheckedVarArgs,
8808 UncoveredArgHandler &UncoveredArg,
8809 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8810 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8811 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8812 inFunctionCall, CallType, CheckedVarArgs,
8814 Specs(Specs), HadError(
false) {}
8818 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8820 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8822 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8823 const char *startSpecifier,
8824 unsigned specifierLen,
8825 const TargetInfo &
Target)
override;
8830bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8832 unsigned specifierLen) {
8836 return HandleInvalidConversionSpecifier(
8841void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8842 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8850 return T->isRecordType() ||
T->isComplexType();
8853bool CheckPrintfHandler::HandleAmount(
8855 const char *startSpecifier,
unsigned specifierLen) {
8857 if (HasFormatArguments()) {
8859 if (argIndex >= NumDataArgs) {
8860 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8864 getSpecifierRange(startSpecifier, specifierLen));
8874 CoveredArgs.set(argIndex);
8875 const Expr *Arg = getDataArg(argIndex);
8886 ? diag::err_printf_asterisk_wrong_type
8887 : diag::warn_printf_asterisk_wrong_type;
8888 EmitFormatDiagnostic(S.
PDiag(DiagID)
8893 getSpecifierRange(startSpecifier, specifierLen));
8903void CheckPrintfHandler::HandleInvalidAmount(
8906 const char *startSpecifier,
unsigned specifierLen) {
8916 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8920 getSpecifierRange(startSpecifier, specifierLen), fixit);
8925 const char *startSpecifier,
8926 unsigned specifierLen) {
8930 EmitFormatDiagnostic(
8931 S.
PDiag(diag::warn_printf_nonsensical_flag)
8935 getSpecifierRange(startSpecifier, specifierLen),
8939void CheckPrintfHandler::HandleIgnoredFlag(
8943 unsigned specifierLen) {
8945 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8949 getSpecifierRange(startSpecifier, specifierLen),
8951 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8954void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8957 EmitFormatDiagnostic(
8958 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8959 true, getSpecifierRange(startFlag, flagLen));
8962void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8965 auto Range = getSpecifierRange(startFlag, flagLen);
8966 StringRef flag(startFlag, flagLen);
8967 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8968 getLocationOfByte(startFlag),
8973void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8974 const char *flagsStart,
const char *flagsEnd,
8975 const char *conversionPosition) {
8977 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8978 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8979 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8980 getLocationOfByte(conversionPosition),
8986 const Expr *FmtExpr,
8987 bool InFunctionCall)
const {
8988 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8989 ElementLoc,
true, Range);
8992bool EquatableFormatArgument::VerifyCompatible(
8993 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8994 bool InFunctionCall)
const {
8999 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
9000 FmtExpr, InFunctionCall);
9001 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
9005 if (
Role != FAR_Data) {
9006 if (ModifierFor !=
Other.ModifierFor) {
9009 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
9010 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
9011 FmtExpr, InFunctionCall);
9012 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
9018 bool HadError =
false;
9019 if (Sensitivity !=
Other.Sensitivity) {
9022 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
9023 << Sensitivity <<
Other.Sensitivity,
9024 FmtExpr, InFunctionCall);
9025 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9026 << 0 <<
Other.Range;
9029 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
9033 case MK::MatchPromotion:
9037 case MK::NoMatchTypeConfusion:
9038 case MK::NoMatchPromotionTypeConfusion:
9040 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
9041 << buildFormatSpecifier()
9042 <<
Other.buildFormatSpecifier(),
9043 FmtExpr, InFunctionCall);
9044 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9045 << 0 <<
Other.Range;
9048 case MK::NoMatchPedantic:
9050 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
9051 << buildFormatSpecifier()
9052 <<
Other.buildFormatSpecifier(),
9053 FmtExpr, InFunctionCall);
9054 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9055 << 0 <<
Other.Range;
9058 case MK::NoMatchSignedness:
9060 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
9061 << buildFormatSpecifier()
9062 <<
Other.buildFormatSpecifier(),
9063 FmtExpr, InFunctionCall);
9064 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9065 << 0 <<
Other.Range;
9071bool DecomposePrintfHandler::GetSpecifiers(
9072 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
9075 StringRef
Data = FSL->getString();
9076 const char *Str =
Data.data();
9077 llvm::SmallBitVector BV;
9078 UncoveredArgHandler UA;
9079 const Expr *PrintfArgs[] = {FSL->getFormatString()};
9080 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
9092 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
9093 const EquatableFormatArgument &B) {
9094 return A.getPosition() < B.getPosition();
9099bool DecomposePrintfHandler::HandlePrintfSpecifier(
9102 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
9117 const unsigned Unset = ~0;
9118 unsigned FieldWidthIndex = Unset;
9119 unsigned PrecisionIndex = Unset;
9123 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
9124 FieldWidthIndex = Specs.size();
9126 getSpecifierRange(startSpecifier, specifierLen),
9127 getLocationOfByte(FieldWidth.getStart()),
9129 FieldWidth.getArgType(S.
Context),
9130 EquatableFormatArgument::FAR_FieldWidth,
9131 EquatableFormatArgument::SS_None,
9132 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
9138 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
9139 PrecisionIndex = Specs.size();
9141 getSpecifierRange(startSpecifier, specifierLen),
9142 getLocationOfByte(Precision.getStart()),
9144 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
9145 EquatableFormatArgument::SS_None,
9146 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
9152 unsigned SpecIndex =
9154 if (FieldWidthIndex != Unset)
9155 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
9156 if (PrecisionIndex != Unset)
9157 Specs[PrecisionIndex].setModifierFor(SpecIndex);
9159 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
9161 Sensitivity = EquatableFormatArgument::SS_Private;
9163 Sensitivity = EquatableFormatArgument::SS_Public;
9165 Sensitivity = EquatableFormatArgument::SS_Sensitive;
9167 Sensitivity = EquatableFormatArgument::SS_None;
9170 getSpecifierRange(startSpecifier, specifierLen),
9173 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
9178 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
9183 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
9184 SpecIndex + 1, SpecIndex);
9192template<
typename MemberKind>
9203 R.suppressDiagnostics();
9210 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
9225 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9227 if ((*MI)->getMinRequiredArguments() == 0)
9235bool CheckPrintfHandler::checkForCStrMembers(
9242 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9245 if (
Method->getMinRequiredArguments() == 0 &&
9258bool CheckPrintfHandler::HandlePrintfSpecifier(
9271 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
9272 startSpecifier, specifierLen);
9284 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
9289 if (!CS.consumesDataArgument()) {
9297 if (argIndex < NumDataArgs) {
9301 CoveredArgs.set(argIndex);
9308 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9311 if (HasFormatArguments()) {
9313 CoveredArgs.set(argIndex + 1);
9316 const Expr *Ex = getDataArg(argIndex);
9320 : ArgType::CPointerTy;
9322 EmitFormatDiagnostic(
9323 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9327 getSpecifierRange(startSpecifier, specifierLen));
9330 Ex = getDataArg(argIndex + 1);
9333 EmitFormatDiagnostic(
9334 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9338 getSpecifierRange(startSpecifier, specifierLen));
9345 if (!allowsObjCArg() && CS.isObjCArg()) {
9346 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9353 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9360 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9361 getLocationOfByte(CS.getStart()),
9363 getSpecifierRange(startSpecifier, specifierLen));
9373 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9380 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9384 getSpecifierRange(startSpecifier, specifierLen));
9387 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9391 getSpecifierRange(startSpecifier, specifierLen));
9395 const llvm::Triple &Triple =
Target.getTriple();
9397 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9398 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9399 getLocationOfByte(CS.getStart()),
9401 getSpecifierRange(startSpecifier, specifierLen));
9407 startSpecifier, specifierLen);
9413 startSpecifier, specifierLen);
9419 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9420 getLocationOfByte(startSpecifier),
9422 getSpecifierRange(startSpecifier, specifierLen));
9431 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9433 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9442 startSpecifier, specifierLen);
9445 startSpecifier, specifierLen);
9450 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9451 diag::warn_format_nonsensical_length);
9453 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9455 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9456 diag::warn_format_non_standard_conversion_spec);
9459 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9462 if (!HasFormatArguments())
9465 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9468 const Expr *Arg = getDataArg(argIndex);
9472 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9484 case Stmt::ArraySubscriptExprClass:
9485 case Stmt::CallExprClass:
9486 case Stmt::CharacterLiteralClass:
9487 case Stmt::CXXBoolLiteralExprClass:
9488 case Stmt::DeclRefExprClass:
9489 case Stmt::FloatingLiteralClass:
9490 case Stmt::IntegerLiteralClass:
9491 case Stmt::MemberExprClass:
9492 case Stmt::ObjCArrayLiteralClass:
9493 case Stmt::ObjCBoolLiteralExprClass:
9494 case Stmt::ObjCBoxedExprClass:
9495 case Stmt::ObjCDictionaryLiteralClass:
9496 case Stmt::ObjCEncodeExprClass:
9497 case Stmt::ObjCIvarRefExprClass:
9498 case Stmt::ObjCMessageExprClass:
9499 case Stmt::ObjCPropertyRefExprClass:
9500 case Stmt::ObjCStringLiteralClass:
9501 case Stmt::ObjCSubscriptRefExprClass:
9502 case Stmt::ParenExprClass:
9503 case Stmt::StringLiteralClass:
9504 case Stmt::UnaryOperatorClass:
9511static std::pair<QualType, StringRef>
9517 StringRef Name = UserTy->getDecl()->getName();
9518 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9519 .Case(
"CFIndex", Context.getNSIntegerType())
9520 .Case(
"NSInteger", Context.getNSIntegerType())
9521 .Case(
"NSUInteger", Context.getNSUIntegerType())
9522 .Case(
"SInt32", Context.IntTy)
9523 .Case(
"UInt32", Context.UnsignedIntTy)
9527 return std::make_pair(CastTy, Name);
9529 TyTy = UserTy->desugar();
9533 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9543 StringRef TrueName, FalseName;
9546 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9548 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9550 if (TrueTy == FalseTy)
9551 return std::make_pair(TrueTy, TrueName);
9552 else if (TrueTy.
isNull())
9553 return std::make_pair(FalseTy, FalseName);
9554 else if (FalseTy.
isNull())
9555 return std::make_pair(TrueTy, TrueName);
9558 return std::make_pair(
QualType(), StringRef());
9577 From = VecTy->getElementType();
9579 To = VecTy->getElementType();
9590 diag::warn_format_conversion_argument_type_mismatch_signedness,
9594 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9601bool CheckPrintfHandler::checkFormatExpr(
9603 unsigned SpecifierLen,
const Expr *E) {
9614 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9618 if (
const OverflowBehaviorType *OBT =
9619 dyn_cast<OverflowBehaviorType>(
ExprTy.getCanonicalType()))
9620 ExprTy = OBT->getUnderlyingType();
9625 if (
ExprTy->canDecayToPointerType())
9634 getSpecifierRange(StartSpecifier, SpecifierLen);
9636 llvm::raw_svector_ostream os(FSString);
9638 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9647 ExprTy->isObjCObjectPointerType()) {
9649 getSpecifierRange(StartSpecifier, SpecifierLen);
9650 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9655 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9663 if (
Match == ArgType::Match)
9667 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9676 E = ICE->getSubExpr();
9686 if (OrigMatch == ArgType::NoMatchSignedness &&
9687 ImplicitMatch != ArgType::NoMatchSignedness)
9694 if (ImplicitMatch == ArgType::Match)
9712 if (
Match == ArgType::MatchPromotion)
9716 if (
Match == ArgType::MatchPromotion) {
9720 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9721 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9725 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9726 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9727 Match = ImplicitMatch;
9728 assert(
Match != ArgType::MatchPromotion);
9731 bool IsEnum =
false;
9732 bool IsScopedEnum =
false;
9734 if (
const auto *ED =
ExprTy->getAsEnumDecl()) {
9735 IntendedTy = ED->getIntegerType();
9736 if (!ED->isScoped()) {
9742 IsScopedEnum =
true;
9749 if (isObjCContext() &&
9751 if (
ExprTy->isIntegralOrUnscopedEnumerationType() &&
9760 const llvm::APInt &
V = IL->getValue();
9770 if (TD->getUnderlyingType() == IntendedTy)
9780 bool ShouldNotPrintDirectly =
false;
9781 StringRef CastTyName;
9784 std::tie(CastTy, CastTyName) =
9790 if (!IsScopedEnum &&
9791 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9795 IntendedTy = CastTy;
9796 ShouldNotPrintDirectly =
true;
9801 PrintfSpecifier fixedFS = FS;
9808 llvm::raw_svector_ostream os(buf);
9811 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9813 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9819 llvm_unreachable(
"expected non-matching");
9821 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9824 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9827 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9830 Diag = diag::warn_format_conversion_argument_type_mismatch;
9851 llvm::raw_svector_ostream CastFix(CastBuf);
9852 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9854 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9860 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9865 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9887 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9893 Name = TypedefTy->getDecl()->getName();
9897 ? diag::warn_format_argument_needs_cast_pedantic
9898 : diag::warn_format_argument_needs_cast;
9899 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9910 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9911 : diag::warn_format_conversion_argument_type_mismatch;
9913 EmitFormatDiagnostic(
9921 getSpecifierRange(StartSpecifier, SpecifierLen);
9925 bool EmitTypeMismatch =
false;
9929 bool EmitOSLogError =
false;
9938 llvm_unreachable(
"expected non-matching");
9940 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9943 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9946 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9950 Diag = diag::warn_format_conversion_argument_type_mismatch;
9954 if (!EmitOSLogError)
9955 EmitFormatDiagnostic(
9964 EmitTypeMismatch =
true;
9968 EmitOSLogError =
true;
9970 EmitFormatDiagnostic(
9971 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9972 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9976 checkForCStrMembers(AT, E);
9982 EmitTypeMismatch =
true;
9983 else if (
ExprTy->isObjCObjectType())
9984 EmitFormatDiagnostic(
9985 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9986 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
10000 EmitFormatDiagnostic(
10001 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
10006 if (EmitTypeMismatch) {
10012 EmitFormatDiagnostic(
10013 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
10019 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
10020 "format string specifier index out of range");
10021 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
10031class CheckScanfHandler :
public CheckFormatHandler {
10033 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
10035 unsigned firstDataArg,
unsigned numDataArgs,
10037 ArrayRef<const Expr *> Args,
unsigned formatIdx,
10039 llvm::SmallBitVector &CheckedVarArgs,
10040 UncoveredArgHandler &UncoveredArg)
10041 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
10042 numDataArgs, beg, APK, Args, formatIdx,
10043 inFunctionCall, CallType, CheckedVarArgs,
10046 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
10047 const char *startSpecifier,
10048 unsigned specifierLen)
override;
10051 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
10052 const char *startSpecifier,
10053 unsigned specifierLen)
override;
10055 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
10060void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
10062 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
10063 getLocationOfByte(end),
true,
10064 getSpecifierRange(start, end - start));
10067bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
10069 unsigned specifierLen) {
10073 return HandleInvalidConversionSpecifier(
10078bool CheckScanfHandler::HandleScanfSpecifier(
10080 unsigned specifierLen) {
10090 atFirstArg =
false;
10093 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
10094 startSpecifier, specifierLen);
10105 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
10106 getLocationOfByte(Amt.
getStart()),
10120 if (argIndex < NumDataArgs) {
10124 CoveredArgs.set(argIndex);
10130 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
10131 diag::warn_format_nonsensical_length);
10133 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
10135 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
10136 diag::warn_format_non_standard_conversion_spec);
10139 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
10142 if (!HasFormatArguments())
10145 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
10149 const Expr *Ex = getDataArg(argIndex);
10159 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
10170 ScanfSpecifier fixedFS = FS;
10175 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
10177 ? diag::warn_format_conversion_argument_type_mismatch_signedness
10178 : diag::warn_format_conversion_argument_type_mismatch;
10183 llvm::raw_svector_ostream os(buf);
10186 EmitFormatDiagnostic(
10191 getSpecifierRange(startSpecifier, specifierLen),
10193 getSpecifierRange(startSpecifier, specifierLen), os.str()));
10200 getSpecifierRange(startSpecifier, specifierLen));
10210 const Expr *FmtExpr,
bool InFunctionCall) {
10211 bool HadError =
false;
10212 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
10213 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
10214 while (FmtIter < FmtEnd && RefIter < RefEnd) {
10226 for (; FmtIter < FmtEnd; ++FmtIter) {
10230 if (FmtIter->getPosition() < RefIter->getPosition())
10234 if (FmtIter->getPosition() > RefIter->getPosition())
10238 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
10242 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
10243 return Arg.getPosition() != RefIter->getPosition();
10247 if (FmtIter < FmtEnd) {
10248 CheckFormatHandler::EmitFormatDiagnostic(
10249 S, InFunctionCall, FmtExpr,
10250 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
10251 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
10252 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
10253 }
else if (RefIter < RefEnd) {
10254 CheckFormatHandler::EmitFormatDiagnostic(
10255 S, InFunctionCall, FmtExpr,
10256 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
10259 << 1 << RefIter->getSourceRange();
10265 Sema &S,
const FormatStringLiteral *FExpr,
10270 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
10271 bool IgnoreStringsWithoutSpecifiers) {
10273 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
10274 CheckFormatHandler::EmitFormatDiagnostic(
10275 S, inFunctionCall, Args[format_idx],
10276 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
10282 StringRef StrRef = FExpr->getString();
10283 const char *Str = StrRef.data();
10287 assert(
T &&
"String literal not of constant array type!");
10288 size_t TypeSize =
T->getZExtSize();
10289 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10290 const unsigned numDataArgs = Args.size() - firstDataArg;
10292 if (IgnoreStringsWithoutSpecifiers &&
10299 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
10300 CheckFormatHandler::EmitFormatDiagnostic(
10301 S, inFunctionCall, Args[format_idx],
10302 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
10303 FExpr->getBeginLoc(),
10309 if (StrLen == 0 && numDataArgs > 0) {
10310 CheckFormatHandler::EmitFormatDiagnostic(
10311 S, inFunctionCall, Args[format_idx],
10312 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10323 if (ReferenceFormatString ==
nullptr) {
10324 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10325 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10326 inFunctionCall, CallType, CheckedVarArgs,
10333 H.DoneProcessing();
10336 Type, ReferenceFormatString, FExpr->getFormatString(),
10337 inFunctionCall ?
nullptr : Args[format_idx]);
10340 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10341 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10342 CallType, CheckedVarArgs, UncoveredArg);
10346 H.DoneProcessing();
10362 FormatStringLiteral RefLit = AuthoritativeFormatString;
10363 FormatStringLiteral TestLit = TestedFormatString;
10365 bool DiagAtStringLiteral;
10366 if (FunctionCallArg) {
10367 Arg = FunctionCallArg;
10368 DiagAtStringLiteral =
false;
10370 Arg = TestedFormatString;
10371 DiagAtStringLiteral =
true;
10373 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10374 AuthoritativeFormatString,
Type,
10375 IsObjC,
true, RefArgs) &&
10376 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10377 DiagAtStringLiteral, FmtArgs)) {
10379 TestedFormatString, FmtArgs, Arg,
10380 DiagAtStringLiteral);
10393 FormatStringLiteral RefLit = Str;
10397 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10406 bool HadError =
false;
10407 auto Iter = Args.begin();
10408 auto End = Args.end();
10409 while (Iter != End) {
10410 const auto &FirstInGroup = *Iter;
10412 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10414 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10423 const char *Str = StrRef.data();
10426 assert(
T &&
"String literal not of constant array type!");
10427 size_t TypeSize =
T->getZExtSize();
10428 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10438 switch (AbsFunction) {
10442 case Builtin::BI__builtin_abs:
10443 return Builtin::BI__builtin_labs;
10444 case Builtin::BI__builtin_labs:
10445 return Builtin::BI__builtin_llabs;
10446 case Builtin::BI__builtin_llabs:
10449 case Builtin::BI__builtin_fabsf:
10450 return Builtin::BI__builtin_fabs;
10451 case Builtin::BI__builtin_fabs:
10452 return Builtin::BI__builtin_fabsl;
10453 case Builtin::BI__builtin_fabsl:
10456 case Builtin::BI__builtin_cabsf:
10457 return Builtin::BI__builtin_cabs;
10458 case Builtin::BI__builtin_cabs:
10459 return Builtin::BI__builtin_cabsl;
10460 case Builtin::BI__builtin_cabsl:
10463 case Builtin::BIabs:
10464 return Builtin::BIlabs;
10465 case Builtin::BIlabs:
10466 return Builtin::BIllabs;
10467 case Builtin::BIllabs:
10470 case Builtin::BIfabsf:
10471 return Builtin::BIfabs;
10472 case Builtin::BIfabs:
10473 return Builtin::BIfabsl;
10474 case Builtin::BIfabsl:
10477 case Builtin::BIcabsf:
10478 return Builtin::BIcabs;
10479 case Builtin::BIcabs:
10480 return Builtin::BIcabsl;
10481 case Builtin::BIcabsl:
10488 unsigned AbsType) {
10510 unsigned AbsFunctionKind) {
10511 unsigned BestKind = 0;
10512 uint64_t ArgSize = Context.getTypeSize(ArgType);
10513 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10516 if (Context.getTypeSize(ParamType) >= ArgSize) {
10519 else if (Context.hasSameType(ParamType, ArgType)) {
10535 if (
T->isIntegralOrEnumerationType())
10537 if (
T->isRealFloatingType())
10539 if (
T->isAnyComplexType())
10542 llvm_unreachable(
"Type not integer, floating, or complex");
10549 switch (ValueKind) {
10554 case Builtin::BI__builtin_fabsf:
10555 case Builtin::BI__builtin_fabs:
10556 case Builtin::BI__builtin_fabsl:
10557 case Builtin::BI__builtin_cabsf:
10558 case Builtin::BI__builtin_cabs:
10559 case Builtin::BI__builtin_cabsl:
10560 return Builtin::BI__builtin_abs;
10561 case Builtin::BIfabsf:
10562 case Builtin::BIfabs:
10563 case Builtin::BIfabsl:
10564 case Builtin::BIcabsf:
10565 case Builtin::BIcabs:
10566 case Builtin::BIcabsl:
10567 return Builtin::BIabs;
10573 case Builtin::BI__builtin_abs:
10574 case Builtin::BI__builtin_labs:
10575 case Builtin::BI__builtin_llabs:
10576 case Builtin::BI__builtin_cabsf:
10577 case Builtin::BI__builtin_cabs:
10578 case Builtin::BI__builtin_cabsl:
10579 return Builtin::BI__builtin_fabsf;
10580 case Builtin::BIabs:
10581 case Builtin::BIlabs:
10582 case Builtin::BIllabs:
10583 case Builtin::BIcabsf:
10584 case Builtin::BIcabs:
10585 case Builtin::BIcabsl:
10586 return Builtin::BIfabsf;
10592 case Builtin::BI__builtin_abs:
10593 case Builtin::BI__builtin_labs:
10594 case Builtin::BI__builtin_llabs:
10595 case Builtin::BI__builtin_fabsf:
10596 case Builtin::BI__builtin_fabs:
10597 case Builtin::BI__builtin_fabsl:
10598 return Builtin::BI__builtin_cabsf;
10599 case Builtin::BIabs:
10600 case Builtin::BIlabs:
10601 case Builtin::BIllabs:
10602 case Builtin::BIfabsf:
10603 case Builtin::BIfabs:
10604 case Builtin::BIfabsl:
10605 return Builtin::BIcabsf;
10608 llvm_unreachable(
"Unable to convert function");
10619 case Builtin::BI__builtin_abs:
10620 case Builtin::BI__builtin_fabs:
10621 case Builtin::BI__builtin_fabsf:
10622 case Builtin::BI__builtin_fabsl:
10623 case Builtin::BI__builtin_labs:
10624 case Builtin::BI__builtin_llabs:
10625 case Builtin::BI__builtin_cabs:
10626 case Builtin::BI__builtin_cabsf:
10627 case Builtin::BI__builtin_cabsl:
10628 case Builtin::BIabs:
10629 case Builtin::BIlabs:
10630 case Builtin::BIllabs:
10631 case Builtin::BIfabs:
10632 case Builtin::BIfabsf:
10633 case Builtin::BIfabsl:
10634 case Builtin::BIcabs:
10635 case Builtin::BIcabsf:
10636 case Builtin::BIcabsl:
10639 llvm_unreachable(
"Unknown Builtin type");
10645 unsigned AbsKind,
QualType ArgType) {
10646 bool EmitHeaderHint =
true;
10647 const char *HeaderName =
nullptr;
10648 std::string FunctionName;
10649 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10650 FunctionName =
"std::abs";
10651 if (ArgType->isIntegralOrEnumerationType()) {
10652 HeaderName =
"cstdlib";
10653 }
else if (ArgType->isRealFloatingType()) {
10654 HeaderName =
"cmath";
10656 llvm_unreachable(
"Invalid Type");
10662 R.suppressDiagnostics();
10665 for (
const auto *I : R) {
10668 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10670 FDecl = dyn_cast<FunctionDecl>(I);
10685 EmitHeaderHint =
false;
10697 R.suppressDiagnostics();
10700 if (R.isSingleResult()) {
10701 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10703 EmitHeaderHint =
false;
10707 }
else if (!R.empty()) {
10713 S.
Diag(Loc, diag::note_replace_abs_function)
10719 if (!EmitHeaderHint)
10722 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10726template <std::
size_t StrLen>
10728 const char (&Str)[StrLen]) {
10741 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10742 return llvm::is_contained(names, calleeName);
10747 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10748 "__builtin_nanf16",
"__builtin_nanf128"});
10750 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10751 "__builtin_inff16",
"__builtin_inff128"});
10753 llvm_unreachable(
"unknown MathCheck");
10757 if (FDecl->
getName() !=
"infinity")
10760 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10762 if (RDecl->
getName() !=
"numeric_limits")
10779 if (FPO.getNoHonorNaNs() &&
10782 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10783 << 1 << 0 <<
Call->getSourceRange();
10787 if (FPO.getNoHonorInfs() &&
10791 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10792 << 0 << 0 <<
Call->getSourceRange();
10796void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10798 if (
Call->getNumArgs() != 1)
10803 if (AbsKind == 0 && !IsStdAbs)
10806 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10807 QualType ParamType =
Call->getArg(0)->getType();
10812 std::string FunctionName =
10813 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10814 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10815 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10850 if (ArgValueKind == ParamValueKind) {
10851 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10855 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10856 << FDecl << ArgType << ParamType;
10858 if (NewAbsKind == 0)
10862 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10871 if (NewAbsKind == 0)
10874 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10875 << FDecl << ParamValueKind << ArgValueKind;
10878 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10884 if (!
Call || !FDecl)
return;
10888 if (
Call->getExprLoc().isMacroID())
return;
10891 if (
Call->getNumArgs() != 2)
return;
10894 if (!ArgList)
return;
10895 if (ArgList->size() != 1)
return;
10898 const auto& TA = ArgList->
get(0);
10900 QualType ArgType = TA.getAsType();
10904 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10905 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10906 if (!MTE)
return false;
10907 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10908 if (!
Num)
return false;
10909 if (
Num->getValue() != 0)
return false;
10913 const Expr *FirstArg =
Call->getArg(0);
10914 const Expr *SecondArg =
Call->getArg(1);
10915 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10916 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10919 if (IsFirstArgZero == IsSecondArgZero)
return;
10924 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10926 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10927 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10930 SourceRange RemovalRange;
10931 if (IsFirstArgZero) {
10932 RemovalRange = SourceRange(FirstRange.
getBegin(),
10939 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10954 const auto *Size = dyn_cast<BinaryOperator>(E);
10959 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10963 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10964 << SizeRange << FnName;
10965 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10970 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10981 bool &IsContained) {
10983 const Type *Ty =
T->getBaseElementTypeUnsafe();
10984 IsContained =
false;
10997 for (
auto *FD : RD->
fields()) {
11001 IsContained =
true;
11002 return ContainedRD;
11010 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
11011 if (Unary->getKind() == UETT_SizeOf)
11020 if (!
SizeOf->isArgumentType())
11021 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
11028 return SizeOf->getTypeOfArgument();
11034struct SearchNonTrivialToInitializeField
11037 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
11039 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
11042 SourceLocation SL) {
11043 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
11044 asDerived().visitArray(PDIK, AT, SL);
11048 Super::visitWithKind(PDIK, FT, SL);
11051 void visitARCStrong(QualType FT, SourceLocation SL) {
11054 void visitARCWeak(QualType FT, SourceLocation SL) {
11057 void visitStruct(QualType FT, SourceLocation SL) {
11062 const ArrayType *AT, SourceLocation SL) {
11063 visit(getContext().getBaseElementType(AT), SL);
11065 void visitTrivial(QualType FT, SourceLocation SL) {}
11067 static void diag(QualType RT,
const Expr *E, Sema &S) {
11068 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
11077struct SearchNonTrivialToCopyField
11079 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
11081 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
11084 SourceLocation SL) {
11085 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
11086 asDerived().visitArray(PCK, AT, SL);
11090 Super::visitWithKind(PCK, FT, SL);
11093 void visitARCStrong(QualType FT, SourceLocation SL) {
11096 void visitARCWeak(QualType FT, SourceLocation SL) {
11099 void visitPtrAuth(QualType FT, SourceLocation SL) {
11102 void visitStruct(QualType FT, SourceLocation SL) {
11107 SourceLocation SL) {
11108 visit(getContext().getBaseElementType(AT), SL);
11111 SourceLocation SL) {}
11112 void visitTrivial(QualType FT, SourceLocation SL) {}
11113 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
11115 static void diag(QualType RT,
const Expr *E, Sema &S) {
11116 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
11131 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
11132 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
11165 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
11168 const Expr *SizeArg =
11169 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
11171 auto isLiteralZero = [](
const Expr *E) {
11181 if (isLiteralZero(SizeArg) &&
11188 if (BId == Builtin::BIbzero ||
11191 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
11192 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
11193 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
11194 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
11195 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
11203 if (BId == Builtin::BImemset &&
11207 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
11208 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
11213void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
11220 unsigned ExpectedNumArgs =
11221 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
11222 if (
Call->getNumArgs() < ExpectedNumArgs)
11225 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
11226 BId == Builtin::BIstrndup ? 1 : 2);
11228 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
11232 Call->getBeginLoc(),
Call->getRParenLoc()))
11244 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
11245 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
11248 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
11252 QualType DestTy = Dest->
getType();
11253 QualType PointeeTy;
11254 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
11266 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
11272 if (SizeOfArgTy != QualType()) {
11274 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
11276 PDiag(diag::warn_sizeof_pointer_type_memaccess)
11277 << FnName << SizeOfArgTy << ArgIdx
11284 PointeeTy = DestTy;
11287 if (PointeeTy == QualType())
11292 if (
const CXXRecordDecl *ContainedRD =
11295 unsigned OperationType = 0;
11296 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
11299 if (ArgIdx != 0 || IsCmp) {
11300 if (BId == Builtin::BImemcpy)
11302 else if(BId == Builtin::BImemmove)
11309 PDiag(diag::warn_dyn_class_memaccess)
11310 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
11311 << IsContained << ContainedRD << OperationType
11312 <<
Call->getCallee()->getSourceRange());
11314 BId != Builtin::BImemset)
11317 PDiag(diag::warn_arc_object_memaccess)
11318 << ArgIdx << FnName << PointeeTy
11319 <<
Call->getCallee()->getSourceRange());
11326 bool NonTriviallyCopyableCXXRecord =
11330 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11333 PDiag(diag::warn_cstruct_memaccess)
11334 << ArgIdx << FnName << PointeeTy << 0);
11335 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11336 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11337 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11341 PDiag(diag::warn_cxxstruct_memaccess)
11342 << FnName << PointeeTy);
11343 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11346 PDiag(diag::warn_cstruct_memaccess)
11347 << ArgIdx << FnName << PointeeTy << 1);
11348 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11349 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11350 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11354 PDiag(diag::warn_cxxstruct_memaccess)
11355 << FnName << PointeeTy);
11364 PDiag(diag::note_bad_memaccess_silence)
11370bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11372 llvm::FoldingSetNodeID SizeOfArgID;
11378 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11381 QualType DestTy = Dest->
getType();
11382 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11388 if (SizeOfArgID == llvm::FoldingSetNodeID())
11391 llvm::FoldingSetNodeID DestID;
11393 if (DestID == SizeOfArgID) {
11396 unsigned ActionIdx = 0;
11397 StringRef ReadableName = FnName->
getName();
11399 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11400 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11409 SourceLocation SL = SizeOfArg->
getExprLoc();
11424 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11425 << ReadableName << PointeeTy << DestTy << DSR
11428 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11429 << ActionIdx << SSR);
11465 if (CAT->getZExtSize() <= 1)
11473void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11477 unsigned NumArgs =
Call->getNumArgs();
11478 if ((NumArgs != 3) && (NumArgs != 4))
11483 const Expr *CompareWithSrc =
nullptr;
11486 Call->getBeginLoc(),
Call->getRParenLoc()))
11491 CompareWithSrc = Ex;
11494 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11495 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11496 SizeCall->getNumArgs() == 1)
11501 if (!CompareWithSrc)
11508 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11512 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11513 if (!CompareWithSrcDRE ||
11517 const Expr *OriginalSizeArg =
Call->getArg(2);
11518 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11525 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11529 SmallString<128> sizeString;
11530 llvm::raw_svector_ostream
OS(sizeString);
11535 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11542 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11543 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11544 return D1->getDecl() == D2->getDecl();
11549 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11558void Sema::CheckStrncatArguments(
const CallExpr *CE,
11573 unsigned PatternType = 0;
11581 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11582 if (BE->getOpcode() == BO_Sub) {
11583 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11584 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11595 if (PatternType == 0)
11611 QualType DstTy = DstArg->
getType();
11614 if (!isKnownSizeArray) {
11615 if (PatternType == 1)
11616 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11618 Diag(SL, diag::warn_strncat_src_size) << SR;
11622 if (PatternType == 1)
11623 Diag(SL, diag::warn_strncat_large_size) << SR;
11625 Diag(SL, diag::warn_strncat_src_size) << SR;
11627 SmallString<128> sizeString;
11628 llvm::raw_svector_ostream
OS(sizeString);
11636 Diag(SL, diag::note_strncat_wrong_size)
11641void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11650void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11652 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11653 const Decl *D = Lvalue->getDecl();
11654 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11655 if (!DD->getType()->isReferenceType())
11656 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11660 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11661 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11662 Lvalue->getMemberDecl());
11665void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11667 const auto *Lambda = dyn_cast<LambdaExpr>(
11672 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11673 << CalleeName << 2 ;
11676void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11678 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11679 if (Var ==
nullptr)
11683 << CalleeName << 0 << Var;
11686void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11689 llvm::raw_svector_ostream
OS(SizeString);
11692 if (Kind == clang::CK_BitCast &&
11693 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11695 if (Kind == clang::CK_IntegralToPointer &&
11697 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11700 switch (
Cast->getCastKind()) {
11701 case clang::CK_BitCast:
11702 case clang::CK_IntegralToPointer:
11703 case clang::CK_FunctionToPointerDecay:
11712 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11713 << CalleeName << 0 <<
OS.str();
11717void Sema::CheckFreeArguments(
const CallExpr *E) {
11718 const std::string CalleeName =
11723 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11725 case UnaryOperator::Opcode::UO_AddrOf:
11726 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11727 case UnaryOperator::Opcode::UO_Plus:
11728 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11733 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11735 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11737 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11738 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11739 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11745 << CalleeName << 1 ;
11750 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11751 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11755Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11764 Diag(ReturnLoc, diag::warn_null_ret)
11774 if (Op == OO_New || Op == OO_Array_New) {
11775 const FunctionProtoType *Proto
11779 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11785 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11790 if (
Context.getTargetInfo().getTriple().isPPC64())
11802 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11803 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11804 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11805 return FPLiteral && FPCast;
11808 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11814 llvm::APFloat TargetC = FPLiteral->
getValue();
11815 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11816 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11820 Diag(Loc, diag::warn_float_compare_literal)
11821 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11834 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11835 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11836 if (DRL->getDecl() == DRR->getDecl())
11844 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11845 if (FLL->isExact())
11847 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11848 if (FLR->isExact())
11852 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11853 CL &&
CL->getBuiltinCallee())
11856 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11857 CR && CR->getBuiltinCallee())
11861 Diag(Loc, diag::warn_floatingpoint_eq)
11882 IntRange(
unsigned Width,
bool NonNegative)
11883 : Width(Width), NonNegative(NonNegative) {}
11886 unsigned valueBits()
const {
11887 return NonNegative ? Width : Width - 1;
11891 static IntRange forBoolType() {
11892 return IntRange(1,
true);
11896 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11897 return forValueOfCanonicalType(
C,
11902 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11905 if (
const auto *VT = dyn_cast<VectorType>(
T))
11906 T = VT->getElementType().getTypePtr();
11907 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11908 T = MT->getElementType().getTypePtr();
11909 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11910 T = CT->getElementType().getTypePtr();
11911 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11912 T = AT->getValueType().getTypePtr();
11913 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11914 T = OBT->getUnderlyingType().getTypePtr();
11916 if (!
C.getLangOpts().CPlusPlus) {
11919 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11924 if (
Enum->isFixed()) {
11925 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11926 !
Enum->getIntegerType()->isSignedIntegerType());
11929 unsigned NumPositive =
Enum->getNumPositiveBits();
11930 unsigned NumNegative =
Enum->getNumNegativeBits();
11932 if (NumNegative == 0)
11933 return IntRange(NumPositive,
true);
11935 return IntRange(std::max(NumPositive + 1, NumNegative),
11939 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11940 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11953 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11956 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11957 T = VT->getElementType().getTypePtr();
11958 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11959 T = MT->getElementType().getTypePtr();
11960 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11961 T = CT->getElementType().getTypePtr();
11962 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11963 T = AT->getValueType().getTypePtr();
11965 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11966 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11967 T = OBT->getUnderlyingType().getTypePtr();
11969 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11970 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11979 static IntRange
join(IntRange L, IntRange R) {
11980 bool Unsigned = L.NonNegative &&
R.NonNegative;
11981 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11982 L.NonNegative &&
R.NonNegative);
11986 static IntRange bit_and(IntRange L, IntRange R) {
11987 unsigned Bits = std::max(L.Width,
R.Width);
11988 bool NonNegative =
false;
11989 if (L.NonNegative) {
11990 Bits = std::min(Bits, L.Width);
11991 NonNegative =
true;
11993 if (
R.NonNegative) {
11994 Bits = std::min(Bits,
R.Width);
11995 NonNegative =
true;
11997 return IntRange(Bits, NonNegative);
12001 static IntRange sum(IntRange L, IntRange R) {
12002 bool Unsigned = L.NonNegative &&
R.NonNegative;
12003 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
12008 static IntRange difference(IntRange L, IntRange R) {
12012 bool CanWiden = !L.NonNegative || !
R.NonNegative;
12013 bool Unsigned = L.NonNegative &&
R.Width == 0;
12014 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
12020 static IntRange product(IntRange L, IntRange R) {
12024 bool CanWiden = !L.NonNegative && !
R.NonNegative;
12025 bool Unsigned = L.NonNegative &&
R.NonNegative;
12026 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
12031 static IntRange rem(IntRange L, IntRange R) {
12035 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
12043 if (value.isSigned() && value.isNegative())
12044 return IntRange(value.getSignificantBits(),
false);
12046 if (value.getBitWidth() > MaxWidth)
12047 value = value.trunc(MaxWidth);
12051 return IntRange(value.getActiveBits(),
true);
12055 if (result.
isInt())
12062 R = IntRange::join(R, El);
12070 return IntRange::join(R, I);
12085 Ty = AtomicRHS->getValueType();
12104 bool InConstantContext,
12105 bool Approximate) {
12116 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
12117 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
12121 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
12123 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
12124 CE->getCastKind() == CK_BooleanToSignedIntegral;
12127 if (!isIntegerCast)
12128 return OutputTypeRange;
12131 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
12132 InConstantContext, Approximate);
12134 return std::nullopt;
12137 if (SubRange->Width >= OutputTypeRange.Width)
12138 return OutputTypeRange;
12142 return IntRange(SubRange->Width,
12143 SubRange->NonNegative || OutputTypeRange.NonNegative);
12146 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12149 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
12151 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
12152 InConstantContext, Approximate);
12157 Expr *TrueExpr = CO->getTrueExpr();
12159 return std::nullopt;
12161 std::optional<IntRange> L =
12164 return std::nullopt;
12166 Expr *FalseExpr = CO->getFalseExpr();
12168 return std::nullopt;
12170 std::optional<IntRange> R =
12173 return std::nullopt;
12175 return IntRange::join(*L, *R);
12178 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12179 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
12181 switch (BO->getOpcode()) {
12183 llvm_unreachable(
"builtin <=> should have class type");
12194 return IntRange::forBoolType();
12223 Combine = IntRange::bit_and;
12231 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
12232 if (I->getValue() == 1) {
12233 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
12234 return IntRange(R.Width,
true);
12244 case BO_ShrAssign: {
12246 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
12248 return std::nullopt;
12252 if (std::optional<llvm::APSInt> shift =
12253 BO->getRHS()->getIntegerConstantExpr(
C)) {
12254 if (shift->isNonNegative()) {
12255 if (shift->uge(L->Width))
12256 L->Width = (L->NonNegative ? 0 : 1);
12258 L->Width -= shift->getZExtValue();
12272 Combine = IntRange::sum;
12276 if (BO->getLHS()->getType()->isPointerType())
12279 Combine = IntRange::difference;
12284 Combine = IntRange::product;
12293 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
12295 return std::nullopt;
12298 if (std::optional<llvm::APSInt> divisor =
12299 BO->getRHS()->getIntegerConstantExpr(
C)) {
12300 unsigned log2 = divisor->logBase2();
12301 if (
log2 >= L->Width)
12302 L->Width = (L->NonNegative ? 0 : 1);
12304 L->Width = std::min(L->Width -
log2, MaxWidth);
12312 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
12314 return std::nullopt;
12316 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12320 Combine = IntRange::rem;
12332 unsigned opWidth =
C.getIntWidth(
T);
12334 InConstantContext, Approximate);
12336 return std::nullopt;
12339 InConstantContext, Approximate);
12341 return std::nullopt;
12343 IntRange
C = Combine(*L, *R);
12344 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
12345 C.Width = std::min(
C.Width, MaxWidth);
12349 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12350 switch (UO->getOpcode()) {
12353 return IntRange::forBoolType();
12361 if (
GetExprType(E)->hasUnsignedIntegerRepresentation()) {
12367 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12370 return std::nullopt;
12375 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12379 if (
GetExprType(E)->hasUnsignedIntegerRepresentation()) {
12385 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12388 return std::nullopt;
12393 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12403 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) {
12407 if (
const Expr *SourceExpr = OVE->getSourceExpr())
12413 return IntRange(BitField->getBitWidthValue(),
12414 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12417 return std::nullopt;
12423 bool InConstantContext,
12424 bool Approximate) {
12433 const llvm::fltSemantics &Src,
12434 const llvm::fltSemantics &Tgt) {
12435 llvm::APFloat truncated = value;
12438 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12439 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12441 return truncated.bitwiseIsEqual(value);
12450 const llvm::fltSemantics &Src,
12451 const llvm::fltSemantics &Tgt) {
12475 bool IsListInit =
false);
12490 return MacroName !=
"YES" && MacroName !=
"NO" &&
12491 MacroName !=
"true" && MacroName !=
"false";
12499 (!E->
getType()->isSignedIntegerType() ||
12514struct PromotedRange {
12516 llvm::APSInt PromotedMin;
12518 llvm::APSInt PromotedMax;
12520 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12522 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12523 else if (
R.Width >= BitWidth && !
Unsigned) {
12527 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12528 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12530 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12531 .extOrTrunc(BitWidth);
12532 PromotedMin.setIsUnsigned(
Unsigned);
12534 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12535 .extOrTrunc(BitWidth);
12536 PromotedMax.setIsUnsigned(
Unsigned);
12541 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12551 InRangeFlag = 0x40,
12554 Min =
LE | InRangeFlag,
12555 InRange = InRangeFlag,
12556 Max =
GE | InRangeFlag,
12559 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12564 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12565 Value.isUnsigned() == PromotedMin.isUnsigned());
12566 if (!isContiguous()) {
12567 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12568 if (
Value.isMinValue())
return Min;
12569 if (
Value.isMaxValue())
return Max;
12570 if (
Value >= PromotedMin)
return InRange;
12571 if (
Value <= PromotedMax)
return InRange;
12575 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12576 case -1:
return Less;
12577 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12579 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12580 case -1:
return InRange;
12581 case 0:
return Max;
12586 llvm_unreachable(
"impossible compare result");
12589 static std::optional<StringRef>
12591 if (Op == BO_Cmp) {
12593 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12595 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12596 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12597 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12598 return std::nullopt;
12605 }
else if (Op == BO_NE) {
12609 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12616 if (Op == BO_GE || Op == BO_LE)
12617 std::swap(TrueFlag, FalseFlag);
12620 return StringRef(
"true");
12622 return StringRef(
"false");
12623 return std::nullopt;
12630 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12631 if (ICE->getCastKind() != CK_IntegralCast &&
12632 ICE->getCastKind() != CK_NoOp)
12634 E = ICE->getSubExpr();
12643 enum ConstantValueKind {
12648 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12649 return BL->getValue() ? ConstantValueKind::LiteralTrue
12650 : ConstantValueKind::LiteralFalse;
12651 return ConstantValueKind::Miscellaneous;
12656 const llvm::APSInt &
Value,
12657 bool RhsConstant) {
12673 if (
Constant->getType()->isEnumeralType() &&
12679 if (!OtherValueRange)
12684 OtherT = AT->getValueType();
12685 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12689 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12695 bool OtherIsBooleanDespiteType =
12697 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12698 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12702 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12703 Value.isUnsigned());
12704 auto Cmp = OtherPromotedValueRange.compare(
Value);
12711 bool TautologicalTypeCompare =
false;
12713 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12714 Value.isUnsigned());
12715 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12718 TautologicalTypeCompare =
true;
12726 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12735 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12741 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12742 Other->getType()->isUnsignedIntegerOrEnumerationType())
12743 TautologicalTypeCompare =
true;
12748 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12749 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12753 llvm::raw_svector_ostream OS(PrettySourceValue);
12755 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12756 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12757 Constant->IgnoreParenImpCasts())) {
12758 OS << (BL->getValue() ?
"YES" :
"NO");
12763 if (!TautologicalTypeCompare) {
12765 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12771 if (IsObjCSignedCharBool) {
12773 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12774 << OS.str() << *
Result);
12781 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12785 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12786 : diag::warn_tautological_bool_compare)
12788 << OtherIsBooleanDespiteType << *
Result
12795 ? diag::warn_unsigned_enum_always_true_comparison
12796 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12797 : diag::warn_unsigned_always_true_comparison)
12798 : diag::warn_tautological_constant_compare;
12834 if (
T->isIntegralType(S.
Context)) {
12835 std::optional<llvm::APSInt> RHSValue =
12837 std::optional<llvm::APSInt> LHSValue =
12841 if (RHSValue && LHSValue)
12845 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12847 const bool RhsConstant = (
bool)RHSValue;
12848 Expr *Const = RhsConstant ? RHS : LHS;
12850 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12859 if (!
T->hasUnsignedIntegerRepresentation()) {
12873 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12875 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12881 Expr *signedOperand, *unsignedOperand;
12884 "unsigned comparison between two signed integer expressions?");
12885 signedOperand = LHS;
12886 unsignedOperand = RHS;
12888 signedOperand = RHS;
12889 unsignedOperand = LHS;
12895 std::optional<IntRange> signedRange =
12907 if (signedRange->NonNegative)
12919 if (!unsignedRange)
12924 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12926 if (unsignedRange->Width < comparisonWidth)
12931 S.
PDiag(diag::warn_mixed_sign_comparison)
12950 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12955 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12956 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12957 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12958 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12959 << BitfieldEnumDecl;
12966 Init->isValueDependent() ||
12967 Init->isTypeDependent())
12970 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12980 const PreferredTypeAttr *PTAttr =
nullptr;
12982 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12984 ED = PTAttr->getType()->getAsEnumDecl();
12992 bool SignedEnum = ED->getNumNegativeBits() > 0;
12999 unsigned DiagID = 0;
13000 if (SignedEnum && !SignedBitfield) {
13003 ? diag::warn_unsigned_bitfield_assigned_signed_enum
13005 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
13006 }
else if (SignedBitfield && !SignedEnum &&
13007 ED->getNumPositiveBits() == FieldWidth) {
13010 ? diag::warn_signed_bitfield_enum_conversion
13011 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
13014 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
13019 << SignedEnum << TypeRange;
13021 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
13028 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
13029 ED->getNumNegativeBits())
13030 : ED->getNumPositiveBits();
13033 if (BitsNeeded > FieldWidth) {
13037 ? diag::warn_bitfield_too_small_for_enum
13038 : diag::warn_preferred_type_bitfield_too_small_for_enum;
13039 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
13043 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
13053 unsigned OriginalWidth =
Value.getBitWidth();
13059 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
13060 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
13067 if (!
Value.isSigned() ||
Value.isNegative())
13068 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
13069 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
13070 OriginalWidth =
Value.getSignificantBits();
13072 if (OriginalWidth <= FieldWidth)
13076 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
13080 TruncatedValue = TruncatedValue.extend(OriginalWidth);
13081 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
13085 std::string PrettyTrunc =
toString(TruncatedValue, 10);
13087 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
13088 ? diag::warn_impcast_single_bit_bitield_precision_constant
13089 : diag::warn_impcast_bitfield_precision_constant)
13090 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
13091 <<
Init->getSourceRange();
13128 bool PruneControlFlow =
false) {
13135 if (
T.hasAddressSpace())
13137 if (PruneControlFlow) {
13151 bool PruneControlFlow =
false) {
13158 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
13163 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
13164 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
13169 llvm::APFloat
Value(0.0);
13175 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
13180 diag::warn_impcast_float_integer, PruneWarnings);
13183 bool isExact =
false;
13186 T->hasUnsignedIntegerRepresentation());
13187 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
13188 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
13196 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
13197 precision = (precision * 59 + 195) / 196;
13198 Value.toString(PrettySourceValue, precision);
13202 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
13203 << PrettySourceValue);
13206 if (
Result == llvm::APFloat::opOK && isExact) {
13207 if (IsLiteral)
return;
13208 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
13214 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
13217 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
13218 : diag::warn_impcast_float_to_integer_out_of_range,
13221 unsigned DiagID = 0;
13224 DiagID = diag::warn_impcast_literal_float_to_integer;
13225 }
else if (IntegerValue == 0) {
13226 if (
Value.isZero()) {
13228 diag::warn_impcast_float_integer, PruneWarnings);
13231 DiagID = diag::warn_impcast_float_to_integer_zero;
13233 if (IntegerValue.isUnsigned()) {
13234 if (!IntegerValue.isMaxValue()) {
13236 diag::warn_impcast_float_integer, PruneWarnings);
13239 if (!IntegerValue.isMaxSignedValue() &&
13240 !IntegerValue.isMinSignedValue()) {
13242 diag::warn_impcast_float_integer, PruneWarnings);
13246 DiagID = diag::warn_impcast_float_to_integer;
13251 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
13253 IntegerValue.toString(PrettyTargetValue);
13255 if (PruneWarnings) {
13258 << E->
getType() <<
T.getUnqualifiedType()
13259 << PrettySourceValue << PrettyTargetValue
13263 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
13272 "Must be compound assignment operation");
13283 ->getComputationResultType()
13290 if (ResultBT->isInteger())
13292 E->
getExprLoc(), diag::warn_impcast_float_integer);
13294 if (!ResultBT->isFloatingPoint())
13303 diag::warn_impcast_float_result_precision);
13308 if (!Range.Width)
return "0";
13310 llvm::APSInt ValueInRange =
Value;
13311 ValueInRange.setIsSigned(!Range.NonNegative);
13312 ValueInRange = ValueInRange.trunc(Range.Width);
13313 return toString(ValueInRange, 10);
13323 const Type *Source =
13325 if (
Target->isDependentType())
13328 const auto *FloatCandidateBT =
13329 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13330 const Type *BoolCandidateType = ToBool ?
Target : Source;
13333 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13338 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13344 S, TheCall->
getArg(I - 1),
false));
13346 S, TheCall->
getArg(I + 1),
false));
13351 diag::warn_impcast_floating_point_to_bool);
13366 if (!IsGNUNullExpr && !HasNullPtrType)
13370 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
13371 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
13374 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13387 if (IsGNUNullExpr && Loc.
isMacroID()) {
13390 if (MacroName ==
"NULL")
13398 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13413 const char FirstLiteralCharacter =
13415 if (FirstLiteralCharacter ==
'0')
13421 if (
T->isCharType() && !
T->isSignedIntegerType() && CC.
isValid()) {
13422 const char FirstContextCharacter =
13424 if (FirstContextCharacter ==
'{')
13432 const auto *IL = dyn_cast<IntegerLiteral>(E);
13434 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13435 if (UO->getOpcode() == UO_Minus)
13436 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13447 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13451 if (Opc == BO_Shl) {
13454 if (LHS && LHS->getValue() == 0)
13455 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13457 RHS->getValue().isNonNegative() &&
13459 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13460 << (
Result.Val.getInt() != 0);
13462 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13469 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13474 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13475 (RHS->getValue() == 0 || RHS->getValue() == 1))
13478 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13479 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13487 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13493 if (Source->isChar16Type() &&
Target->isChar32Type())
13499 llvm::APSInt
Value(32);
13501 bool IsASCII =
Value <= 0x7F;
13502 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13503 bool ConversionPreservesSemantics =
13504 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13506 if (!ConversionPreservesSemantics) {
13507 auto IsSingleCodeUnitCP = [](
const QualType &
T,
13508 const llvm::APSInt &
Value) {
13509 if (
T->isChar8Type())
13510 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13511 if (
T->isChar16Type())
13512 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13513 assert(
T->isChar32Type());
13514 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13517 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13526 LosesPrecision ? diag::warn_impcast_unicode_precision
13527 : diag::warn_impcast_unicode_char_type);
13532 From =
Context.getCanonicalType(From);
13533 To =
Context.getCanonicalType(To);
13536 From = MaybePointee;
13543 if (FromFn->getCFIUncheckedCalleeAttr() &&
13544 !ToFn->getCFIUncheckedCalleeAttr())
13552 bool *ICContext,
bool IsListInit) {
13557 if (Source ==
Target)
return;
13558 if (
Target->isDependentType())
return;
13568 if (Source->isAtomicType())
13572 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13578 diag::warn_impcast_string_literal_to_bool);
13584 diag::warn_impcast_objective_c_literal_to_bool);
13586 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13598 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
13601 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13603 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13612 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13614 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13625 diag::err_impcast_incompatible_type);
13630 ? diag::err_impcast_complex_scalar
13631 : diag::warn_impcast_complex_scalar);
13640 if (
Target->isSveVLSBuiltinType() &&
13647 if (
Target->isRVVVLSBuiltinType() &&
13657 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
13665 diag::warn_hlsl_impcast_vector_truncation);
13677 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13678 Target = VecTy->getElementType().getTypePtr();
13682 if (
Target->isScalarType())
13683 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
13691 diag::warn_hlsl_impcast_matrix_truncation);
13697 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13698 Target = MatTy->getElementType().getTypePtr();
13700 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13706 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
13709 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13711 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13758 else if (Order < 0) {
13768 if (TargetBT && TargetBT->
isInteger()) {
13795 diag::warn_impcast_floating_point_to_bool);
13803 if (Source->isFixedPointType()) {
13804 if (
Target->isUnsaturatedFixedPointType()) {
13808 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13809 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
13810 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
13813 PDiag(diag::warn_impcast_fixed_point_range)
13814 <<
Value.toString() <<
T
13820 }
else if (
Target->isIntegerType()) {
13824 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13827 llvm::APSInt IntResult = FXResult.convertToInt(
13828 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
13833 PDiag(diag::warn_impcast_fixed_point_range)
13834 << FXResult.toString() <<
T
13841 }
else if (
Target->isUnsaturatedFixedPointType()) {
13842 if (Source->isIntegerType()) {
13849 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13854 PDiag(diag::warn_impcast_fixed_point_range)
13875 unsigned int SourcePrecision =
SourceRange->Width;
13879 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13882 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13883 SourcePrecision > TargetPrecision) {
13885 if (std::optional<llvm::APSInt> SourceInt =
13890 llvm::APFloat TargetFloatValue(
13892 llvm::APFloat::opStatus ConversionStatus =
13893 TargetFloatValue.convertFromAPInt(
13895 llvm::APFloat::rmNearestTiesToEven);
13897 if (ConversionStatus != llvm::APFloat::opOK) {
13899 SourceInt->toString(PrettySourceValue, 10);
13901 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13905 PDiag(diag::warn_impcast_integer_float_precision_constant)
13906 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13912 diag::warn_impcast_integer_float_precision);
13921 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13926 if (
Target->isBooleanType())
13930 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13934 if (!Source->isIntegerType() || !
Target->isIntegerType())
13939 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13942 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13945 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13950 if (!LikelySourceRange)
13953 IntRange SourceTypeRange =
13954 IntRange::forTargetOfCanonicalType(
Context, Source);
13955 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13957 if (LikelySourceRange->Width > TargetRange.Width) {
13961 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13962 if (TargetOBT->isWrapKind()) {
13969 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13970 if (SourceOBT->isWrapKind()) {
13980 llvm::APSInt
Value(32);
13990 PDiag(diag::warn_impcast_integer_precision_constant)
13991 << PrettySourceValue << PrettyTargetValue
14001 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
14002 if (UO->getOpcode() == UO_Minus)
14004 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
14007 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
14011 diag::warn_impcast_integer_precision);
14014 if (TargetRange.Width > SourceTypeRange.Width) {
14015 if (
auto *UO = dyn_cast<UnaryOperator>(E))
14016 if (UO->getOpcode() == UO_Minus)
14017 if (Source->isUnsignedIntegerType()) {
14018 if (
Target->isUnsignedIntegerType())
14020 diag::warn_impcast_high_order_zero_bits);
14021 if (
Target->isSignedIntegerType())
14023 diag::warn_impcast_nonnegative_result);
14027 if (TargetRange.Width == LikelySourceRange->Width &&
14028 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
14029 Source->isSignedIntegerType()) {
14043 PDiag(diag::warn_impcast_integer_precision_constant)
14044 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
14054 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
14055 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
14056 LikelySourceRange->Width == TargetRange.Width))) {
14060 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
14062 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
14066 unsigned DiagID = diag::warn_impcast_integer_sign;
14074 DiagID = diag::warn_impcast_integer_sign_conditional;
14091 Source =
Context.getCanonicalType(SourceType).getTypePtr();
14093 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
14094 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
14095 if (SourceEnum->getDecl()->hasNameForLinkage() &&
14096 TargetEnum->getDecl()->hasNameForLinkage() &&
14097 SourceEnum != TargetEnum) {
14102 diag::warn_impcast_different_enum_types);
14116 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
14129 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
14130 TrueExpr = BCO->getCommon();
14132 bool Suspicious =
false;
14136 if (
T->isBooleanType())
14141 if (!Suspicious)
return;
14144 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
14151 Suspicious =
false;
14156 E->
getType(), CC, &Suspicious);
14173struct AnalyzeImplicitConversionsWorkItem {
14182 bool ExtraCheckForImplicitConversion,
14185 WorkList.push_back({E, CC,
false});
14187 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
14194 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
14196 Expr *OrigE = Item.E;
14215 Expr *SourceExpr = E;
14220 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
14221 if (
auto *Src = OVE->getSourceExpr())
14224 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
14225 if (UO->getOpcode() == UO_Not &&
14226 UO->getSubExpr()->isKnownToHaveBooleanValue())
14227 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
14231 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
14232 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
14233 BO->getLHS()->isKnownToHaveBooleanValue() &&
14234 BO->getRHS()->isKnownToHaveBooleanValue() &&
14235 BO->getLHS()->HasSideEffects(S.
Context) &&
14236 BO->getRHS()->HasSideEffects(S.
Context)) {
14247 if (SR.str() ==
"&" || SR.str() ==
"|") {
14249 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
14250 << (BO->getOpcode() == BO_And ?
"&" :
"|")
14253 BO->getOperatorLoc(),
14254 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
14255 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
14257 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
14275 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
14281 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
14296 for (
auto *SE : POE->semantics())
14297 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
14298 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
14302 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
14303 E = CE->getSubExpr();
14309 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
14310 if (InitListE->getNumInits() == 1) {
14311 E = InitListE->getInit(0);
14318 WorkList.push_back({E, CC, IsListInit});
14322 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
14323 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
14327 if (OutArgE->isInOut())
14328 WorkList.push_back(
14329 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14330 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14336 if (BO->isComparisonOp())
14340 if (BO->getOpcode() == BO_Assign)
14343 if (BO->isAssignmentOp())
14359 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14361 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14365 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14366 if (ChildExpr == CSE->getOperand())
14372 if (IsLogicalAndOperator &&
14377 WorkList.push_back({ChildExpr, CC, IsListInit});
14391 if (
U->getOpcode() == UO_LNot) {
14393 }
else if (
U->getOpcode() != UO_AddrOf) {
14394 if (
U->getSubExpr()->getType()->isAtomicType())
14395 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14396 diag::warn_atomic_implicit_seq_cst);
14407 WorkList.push_back({OrigE, CC, IsListInit});
14408 while (!WorkList.empty())
14420 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14423 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14424 if (!M->getMemberDecl()->getType()->isReferenceType())
14426 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14427 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14429 FD =
Call->getDirectCallee();
14438 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14478 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14479 : diag::warn_this_bool_conversion;
14484 bool IsAddressOf =
false;
14486 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14487 if (UO->getOpcode() != UO_AddrOf)
14489 IsAddressOf =
true;
14490 E = UO->getSubExpr();
14494 unsigned DiagID = IsCompare
14495 ? diag::warn_address_of_reference_null_compare
14496 : diag::warn_address_of_reference_bool_conversion;
14504 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14507 llvm::raw_string_ostream S(Str);
14509 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14510 : diag::warn_cast_nonnull_to_bool;
14513 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14518 if (
auto *Callee =
Call->getDirectCallee()) {
14519 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14520 ComplainAboutNonnullParamOrCall(A);
14529 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14530 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14531 MRecordDecl && MRecordDecl->isLambda()) {
14534 << MRecordDecl->getSourceRange() << Range << IsEqual;
14544 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14545 D = M->getMemberDecl();
14553 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14556 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14557 ComplainAboutNonnullParamOrCall(A);
14561 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14565 auto ParamIter = llvm::find(FD->
parameters(), PV);
14567 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14571 ComplainAboutNonnullParamOrCall(
NonNull);
14576 if (ArgNo.getASTIndex() == ParamNo) {
14577 ComplainAboutNonnullParamOrCall(
NonNull);
14588 const bool IsFunctionReference =
14589 T->isReferenceType() &&
T->getPointeeType()->isFunctionType();
14590 if (IsFunctionReference)
14591 T =
T->getPointeeType();
14592 const bool IsArray =
T->isArrayType();
14593 const bool IsFunction =
T->isFunctionType();
14596 if (IsAddressOf && IsFunction) {
14601 if (!IsAddressOf && !IsFunction && !IsArray)
14606 llvm::raw_string_ostream S(Str);
14609 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14610 : diag::warn_impcast_pointer_to_bool;
14617 DiagType = AddressOf;
14618 else if (IsFunction)
14619 DiagType = FunctionPointer;
14621 DiagType = ArrayPointer;
14623 llvm_unreachable(
"Could not determine diagnostic.");
14625 << Range << IsEqual;
14628 if (!IsFunction || IsFunctionReference)
14639 if (ReturnType.
isNull())
14670 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14671 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14673 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14674 Target->isUnsignedIntegerType()) {
14678 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14679 : diag::warn_impcast_overflow_behavior_pedantic;
14683 ? diag::warn_impcast_overflow_behavior_assignment
14684 : diag::warn_impcast_overflow_behavior;
14690 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14691 if (TargetOBT->isWrapKind()) {
14711 CheckArrayAccess(E);
14721void Sema::CheckForIntOverflow (
const Expr *E) {
14723 SmallVector<const Expr *, 2> Exprs(1, E);
14726 const Expr *OriginalE = Exprs.pop_back_val();
14735 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14736 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14739 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14740 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14741 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14743 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14744 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14745 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14746 Exprs.push_back(Temporary->getSubExpr());
14747 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14748 Exprs.push_back(
Array->getIdx());
14749 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14750 Exprs.push_back(Compound->getInitializer());
14751 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14752 New &&
New->isArray()) {
14753 if (
auto ArraySize =
New->getArraySize())
14754 Exprs.push_back(*ArraySize);
14755 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14756 Exprs.push_back(MTE->getSubExpr());
14757 }
while (!Exprs.empty());
14765 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14772 class SequenceTree {
14774 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14775 unsigned Parent : 31;
14776 LLVM_PREFERRED_TYPE(
bool)
14777 unsigned Merged : 1;
14779 SmallVector<Value, 8> Values;
14785 friend class SequenceTree;
14789 explicit Seq(
unsigned N) : Index(N) {}
14792 Seq() : Index(0) {}
14795 SequenceTree() { Values.push_back(
Value(0)); }
14796 Seq root()
const {
return Seq(0); }
14801 Seq allocate(
Seq Parent) {
14802 Values.push_back(
Value(Parent.Index));
14803 return Seq(Values.size() - 1);
14808 Values[S.Index].Merged =
true;
14814 bool isUnsequenced(
Seq Cur,
Seq Old) {
14815 unsigned C = representative(Cur.Index);
14816 unsigned Target = representative(Old.Index);
14820 C = Values[
C].Parent;
14827 unsigned representative(
unsigned K) {
14828 if (Values[K].Merged)
14830 return Values[K].Parent = representative(Values[K].Parent);
14836 using Object =
const NamedDecl *;
14850 UK_ModAsSideEffect,
14852 UK_Count = UK_ModAsSideEffect + 1
14858 const Expr *UsageExpr =
nullptr;
14859 SequenceTree::Seq
Seq;
14865 Usage Uses[UK_Count];
14868 bool Diagnosed =
false;
14872 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14880 UsageInfoMap UsageMap;
14883 SequenceTree::Seq Region;
14887 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14891 SmallVectorImpl<const Expr *> &WorkList;
14898 struct SequencedSubexpression {
14899 SequencedSubexpression(SequenceChecker &
Self)
14900 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14901 Self.ModAsSideEffect = &ModAsSideEffect;
14904 ~SequencedSubexpression() {
14905 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14909 UsageInfo &UI =
Self.UsageMap[M.first];
14910 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14911 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14912 SideEffectUsage = M.second;
14914 Self.ModAsSideEffect = OldModAsSideEffect;
14917 SequenceChecker &
Self;
14918 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14919 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14926 class EvaluationTracker {
14928 EvaluationTracker(SequenceChecker &
Self)
14930 Self.EvalTracker =
this;
14933 ~EvaluationTracker() {
14934 Self.EvalTracker = Prev;
14936 Prev->EvalOK &= EvalOK;
14939 bool evaluate(
const Expr *E,
bool &
Result) {
14944 Self.SemaRef.isConstantEvaluatedContext());
14949 SequenceChecker &
Self;
14950 EvaluationTracker *Prev;
14951 bool EvalOK =
true;
14952 } *EvalTracker =
nullptr;
14956 Object getObject(
const Expr *E,
bool Mod)
const {
14958 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14959 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14960 return getObject(UO->getSubExpr(), Mod);
14961 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14962 if (BO->getOpcode() == BO_Comma)
14963 return getObject(BO->getRHS(), Mod);
14964 if (Mod && BO->isAssignmentOp())
14965 return getObject(BO->getLHS(), Mod);
14966 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14969 return ME->getMemberDecl();
14970 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14979 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14981 Usage &U = UI.Uses[UK];
14982 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14986 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14987 ModAsSideEffect->push_back(std::make_pair(O, U));
14989 U.UsageExpr = UsageExpr;
14999 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
15000 UsageKind OtherKind,
bool IsModMod) {
15004 const Usage &U = UI.Uses[OtherKind];
15005 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
15008 const Expr *Mod = U.UsageExpr;
15009 const Expr *ModOrUse = UsageExpr;
15010 if (OtherKind == UK_Use)
15011 std::swap(Mod, ModOrUse);
15015 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
15016 : diag::warn_unsequenced_mod_use)
15017 << O << SourceRange(ModOrUse->
getExprLoc()));
15018 UI.Diagnosed =
true;
15047 void notePreUse(
Object O,
const Expr *UseExpr) {
15048 UsageInfo &UI = UsageMap[O];
15050 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
15053 void notePostUse(
Object O,
const Expr *UseExpr) {
15054 UsageInfo &UI = UsageMap[O];
15055 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
15057 addUsage(O, UI, UseExpr, UK_Use);
15060 void notePreMod(
Object O,
const Expr *ModExpr) {
15061 UsageInfo &UI = UsageMap[O];
15063 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
15064 checkUsage(O, UI, ModExpr, UK_Use,
false);
15067 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
15068 UsageInfo &UI = UsageMap[O];
15069 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
15071 addUsage(O, UI, ModExpr, UK);
15075 SequenceChecker(Sema &S,
const Expr *E,
15076 SmallVectorImpl<const Expr *> &WorkList)
15077 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
15081 (void)this->WorkList;
15084 void VisitStmt(
const Stmt *S) {
15088 void VisitExpr(
const Expr *E) {
15090 Base::VisitStmt(E);
15093 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
15094 for (
auto *Sub : CSE->
children()) {
15095 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
15110 void VisitCastExpr(
const CastExpr *E) {
15122 void VisitSequencedExpressions(
const Expr *SequencedBefore,
15123 const Expr *SequencedAfter) {
15124 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
15125 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
15126 SequenceTree::Seq OldRegion = Region;
15129 SequencedSubexpression SeqBefore(*
this);
15130 Region = BeforeRegion;
15131 Visit(SequencedBefore);
15134 Region = AfterRegion;
15135 Visit(SequencedAfter);
15137 Region = OldRegion;
15139 Tree.merge(BeforeRegion);
15140 Tree.merge(AfterRegion);
15143 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
15148 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
15155 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15156 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15157 void VisitBinPtrMem(
const BinaryOperator *BO) {
15162 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15169 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15170 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15171 void VisitBinShlShr(
const BinaryOperator *BO) {
15175 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15182 void VisitBinComma(
const BinaryOperator *BO) {
15187 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15190 void VisitBinAssign(
const BinaryOperator *BO) {
15191 SequenceTree::Seq RHSRegion;
15192 SequenceTree::Seq LHSRegion;
15194 RHSRegion = Tree.allocate(Region);
15195 LHSRegion = Tree.allocate(Region);
15197 RHSRegion = Region;
15198 LHSRegion = Region;
15200 SequenceTree::Seq OldRegion = Region;
15216 SequencedSubexpression SeqBefore(*
this);
15217 Region = RHSRegion;
15221 Region = LHSRegion;
15225 notePostUse(O, BO);
15229 Region = LHSRegion;
15233 notePostUse(O, BO);
15235 Region = RHSRegion;
15243 Region = OldRegion;
15247 : UK_ModAsSideEffect);
15249 Tree.merge(RHSRegion);
15250 Tree.merge(LHSRegion);
15254 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
15255 VisitBinAssign(CAO);
15258 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15259 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15260 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
15263 return VisitExpr(UO);
15271 : UK_ModAsSideEffect);
15274 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15275 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15276 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
15279 return VisitExpr(UO);
15283 notePostMod(O, UO, UK_ModAsSideEffect);
15286 void VisitBinLOr(
const BinaryOperator *BO) {
15292 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15293 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15294 SequenceTree::Seq OldRegion = Region;
15296 EvaluationTracker Eval(*
this);
15298 SequencedSubexpression Sequenced(*
this);
15299 Region = LHSRegion;
15306 bool EvalResult =
false;
15307 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15308 bool ShouldVisitRHS = !EvalOK || !EvalResult;
15309 if (ShouldVisitRHS) {
15310 Region = RHSRegion;
15314 Region = OldRegion;
15315 Tree.merge(LHSRegion);
15316 Tree.merge(RHSRegion);
15319 void VisitBinLAnd(
const BinaryOperator *BO) {
15325 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15326 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15327 SequenceTree::Seq OldRegion = Region;
15329 EvaluationTracker Eval(*
this);
15331 SequencedSubexpression Sequenced(*
this);
15332 Region = LHSRegion;
15338 bool EvalResult =
false;
15339 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15340 bool ShouldVisitRHS = !EvalOK || EvalResult;
15341 if (ShouldVisitRHS) {
15342 Region = RHSRegion;
15346 Region = OldRegion;
15347 Tree.merge(LHSRegion);
15348 Tree.merge(RHSRegion);
15351 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15356 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15372 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15373 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15374 SequenceTree::Seq OldRegion = Region;
15376 EvaluationTracker Eval(*
this);
15378 SequencedSubexpression Sequenced(*
this);
15379 Region = ConditionRegion;
15389 bool EvalResult =
false;
15390 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15391 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15392 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15393 if (ShouldVisitTrueExpr) {
15394 Region = TrueRegion;
15397 if (ShouldVisitFalseExpr) {
15398 Region = FalseRegion;
15402 Region = OldRegion;
15403 Tree.merge(ConditionRegion);
15404 Tree.merge(TrueRegion);
15405 Tree.merge(FalseRegion);
15408 void VisitCallExpr(
const CallExpr *CE) {
15420 SequencedSubexpression Sequenced(*
this);
15425 SequenceTree::Seq CalleeRegion;
15426 SequenceTree::Seq OtherRegion;
15427 if (SemaRef.getLangOpts().CPlusPlus17) {
15428 CalleeRegion = Tree.allocate(Region);
15429 OtherRegion = Tree.allocate(Region);
15431 CalleeRegion = Region;
15432 OtherRegion = Region;
15434 SequenceTree::Seq OldRegion = Region;
15437 Region = CalleeRegion;
15439 SequencedSubexpression Sequenced(*this);
15440 Visit(CE->getCallee());
15442 Visit(CE->getCallee());
15446 Region = OtherRegion;
15450 Region = OldRegion;
15452 Tree.merge(CalleeRegion);
15453 Tree.merge(OtherRegion);
15471 return VisitCallExpr(CXXOCE);
15482 case OO_MinusEqual:
15484 case OO_SlashEqual:
15485 case OO_PercentEqual:
15486 case OO_CaretEqual:
15489 case OO_LessLessEqual:
15490 case OO_GreaterGreaterEqual:
15491 SequencingKind = RHSBeforeLHS;
15495 case OO_GreaterGreater:
15501 SequencingKind = LHSBeforeRHS;
15505 SequencingKind = LHSBeforeRest;
15509 SequencingKind = NoSequencing;
15513 if (SequencingKind == NoSequencing)
15514 return VisitCallExpr(CXXOCE);
15517 SequencedSubexpression Sequenced(*
this);
15520 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15521 "Should only get there with C++17 and above!");
15522 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15523 "Should only get there with an overloaded binary operator"
15524 " or an overloaded call operator!");
15526 if (SequencingKind == LHSBeforeRest) {
15527 assert(CXXOCE->getOperator() == OO_Call &&
15528 "We should only have an overloaded call operator here!");
15537 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15538 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15539 SequenceTree::Seq OldRegion = Region;
15541 assert(CXXOCE->getNumArgs() >= 1 &&
15542 "An overloaded call operator must have at least one argument"
15543 " for the postfix-expression!");
15544 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15545 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15546 CXXOCE->getNumArgs() - 1);
15550 Region = PostfixExprRegion;
15551 SequencedSubexpression Sequenced(*this);
15552 Visit(PostfixExpr);
15556 Region = ArgsRegion;
15557 for (const Expr *Arg : Args)
15560 Region = OldRegion;
15561 Tree.merge(PostfixExprRegion);
15562 Tree.merge(ArgsRegion);
15564 assert(CXXOCE->getNumArgs() == 2 &&
15565 "Should only have two arguments here!");
15566 assert((SequencingKind == LHSBeforeRHS ||
15567 SequencingKind == RHSBeforeLHS) &&
15568 "Unexpected sequencing kind!");
15572 const Expr *E1 = CXXOCE->getArg(0);
15573 const Expr *E2 = CXXOCE->getArg(1);
15574 if (SequencingKind == RHSBeforeLHS)
15577 return VisitSequencedExpressions(E1, E2);
15584 SequencedSubexpression Sequenced(*
this);
15587 return VisitExpr(CCE);
15590 SequenceExpressionsInOrder(
15596 return VisitExpr(ILE);
15599 SequenceExpressionsInOrder(ILE->
inits());
15611 SequenceTree::Seq Parent = Region;
15612 for (
const Expr *E : ExpressionList) {
15615 Region = Tree.allocate(Parent);
15616 Elts.push_back(Region);
15622 for (
unsigned I = 0; I < Elts.size(); ++I)
15623 Tree.merge(Elts[I]);
15627SequenceChecker::UsageInfo::UsageInfo() =
default;
15631void Sema::CheckUnsequencedOperations(
const Expr *E) {
15632 SmallVector<const Expr *, 8> WorkList;
15633 WorkList.push_back(E);
15634 while (!WorkList.empty()) {
15635 const Expr *Item = WorkList.pop_back_val();
15636 SequenceChecker(*
this, Item, WorkList);
15641 bool IsConstexpr) {
15644 CheckImplicitConversions(E, CheckLoc);
15646 CheckUnsequencedOperations(E);
15648 CheckForIntOverflow(E);
15661 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15665 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15669 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15683 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15687 bool CheckParameterNames) {
15688 bool HasInvalidParm =
false;
15690 assert(Param &&
"null in a parameter list");
15699 if (!Param->isInvalidDecl() &&
15701 diag::err_typecheck_decl_incomplete_type) ||
15703 diag::err_abstract_type_in_decl,
15705 Param->setInvalidDecl();
15706 HasInvalidParm =
true;
15711 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15715 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15723 QualType PType = Param->getOriginalType();
15731 if (!Param->isInvalidDecl()) {
15732 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15733 if (!ClassDecl->isInvalidDecl() &&
15734 !ClassDecl->hasIrrelevantDestructor() &&
15735 !ClassDecl->isDependentContext() &&
15736 ClassDecl->isParamDestroyedInCallee()) {
15748 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15749 if (!Param->getType().isConstQualified())
15750 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15754 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15759 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15760 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15765 if (!Param->isInvalidDecl() &&
15766 Param->getOriginalType()->isWebAssemblyTableType()) {
15767 Param->setInvalidDecl();
15768 HasInvalidParm =
true;
15769 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15773 return HasInvalidParm;
15776std::optional<std::pair<
15785static std::pair<CharUnits, CharUnits>
15793 if (
Base->isVirtual()) {
15800 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15807 DerivedType =
Base->getType();
15810 return std::make_pair(BaseAlignment, Offset);
15814static std::optional<std::pair<CharUnits, CharUnits>>
15820 return std::nullopt;
15825 return std::nullopt;
15829 CharUnits Offset = EltSize * IdxRes->getExtValue();
15832 return std::make_pair(P->first, P->second + Offset);
15838 return std::make_pair(
15839 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15845std::optional<std::pair<
15853 case Stmt::CStyleCastExprClass:
15854 case Stmt::CXXStaticCastExprClass:
15855 case Stmt::ImplicitCastExprClass: {
15857 const Expr *From = CE->getSubExpr();
15858 switch (CE->getCastKind()) {
15863 case CK_UncheckedDerivedToBase:
15864 case CK_DerivedToBase: {
15874 case Stmt::ArraySubscriptExprClass: {
15879 case Stmt::DeclRefExprClass: {
15883 if (!VD->getType()->isReferenceType()) {
15885 if (VD->hasDependentAlignment())
15894 case Stmt::MemberExprClass: {
15896 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15900 std::optional<std::pair<CharUnits, CharUnits>> P;
15909 return std::make_pair(P->first,
15912 case Stmt::UnaryOperatorClass: {
15922 case Stmt::BinaryOperatorClass: {
15934 return std::nullopt;
15939std::optional<std::pair<
15948 case Stmt::CStyleCastExprClass:
15949 case Stmt::CXXStaticCastExprClass:
15950 case Stmt::ImplicitCastExprClass: {
15952 const Expr *From = CE->getSubExpr();
15953 switch (CE->getCastKind()) {
15958 case CK_ArrayToPointerDecay:
15960 case CK_UncheckedDerivedToBase:
15961 case CK_DerivedToBase: {
15971 case Stmt::CXXThisExprClass: {
15976 case Stmt::UnaryOperatorClass: {
15982 case Stmt::BinaryOperatorClass: {
15991 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15992 std::swap(LHS, RHS);
16002 return std::nullopt;
16007 std::optional<std::pair<CharUnits, CharUnits>> P =
16011 return P->first.alignmentAtOffset(P->second);
16029 if (!DestPtr)
return;
16035 if (DestAlign.
isOne())
return;
16039 if (!SrcPtr)
return;
16050 if (SrcAlign >= DestAlign)
return;
16055 <<
static_cast<unsigned>(DestAlign.
getQuantity())
16059void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
16061 bool AllowOnePastEnd,
bool IndexNegated) {
16070 const Type *EffectiveType =
16074 Context.getAsConstantArrayType(BaseExpr->
getType());
16077 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
16079 const Type *BaseType =
16081 bool IsUnboundedArray =
16083 Context, StrictFlexArraysLevel,
16086 (!IsUnboundedArray && BaseType->isDependentType()))
16094 if (IndexNegated) {
16095 index.setIsUnsigned(
false);
16099 if (IsUnboundedArray) {
16102 if (
index.isUnsigned() || !
index.isNegative()) {
16104 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
16106 if (
index.getBitWidth() < AddrBits)
16108 std::optional<CharUnits> ElemCharUnits =
16109 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
16112 if (!ElemCharUnits || ElemCharUnits->isZero())
16114 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
16119 if (
index.getActiveBits() <= AddrBits) {
16121 llvm::APInt Product(
index);
16123 Product = Product.umul_ov(ElemBytes, Overflow);
16124 if (!Overflow && Product.getActiveBits() <= AddrBits)
16130 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
16131 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
16133 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
16134 MaxElems = MaxElems.udiv(ElemBytes);
16137 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
16138 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
16143 PDiag(DiagID) << index << AddrBits
16144 << (
unsigned)ASTC.toBits(*ElemCharUnits)
16145 << ElemBytes << MaxElems
16146 << MaxElems.getZExtValue()
16149 const NamedDecl *ND =
nullptr;
16151 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16153 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16155 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16156 ND = ME->getMemberDecl();
16160 PDiag(diag::note_array_declared_here) << ND);
16165 if (index.isUnsigned() || !index.isNegative()) {
16175 llvm::APInt size = ArrayTy->
getSize();
16177 if (BaseType != EffectiveType) {
16185 if (!ptrarith_typesize)
16186 ptrarith_typesize =
Context.getCharWidth();
16188 if (ptrarith_typesize != array_typesize) {
16190 uint64_t ratio = array_typesize / ptrarith_typesize;
16194 if (ptrarith_typesize * ratio == array_typesize)
16195 size *= llvm::APInt(size.getBitWidth(), ratio);
16199 if (size.getBitWidth() > index.getBitWidth())
16200 index = index.zext(size.getBitWidth());
16201 else if (size.getBitWidth() < index.getBitWidth())
16202 size = size.zext(index.getBitWidth());
16208 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
16215 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
16217 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
16218 SourceLocation IndexLoc =
16220 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
16225 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
16226 : diag::warn_ptr_arith_exceeds_bounds;
16227 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
16228 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
16232 << index << ArrayTy->
desugar() << CastMsg
16235 unsigned DiagID = diag::warn_array_index_precedes_bounds;
16237 DiagID = diag::warn_ptr_arith_precedes_bounds;
16238 if (index.isNegative()) index = -index;
16245 const NamedDecl *ND =
nullptr;
16247 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16249 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16251 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16252 ND = ME->getMemberDecl();
16256 PDiag(diag::note_array_declared_here) << ND);
16259void Sema::CheckArrayAccess(
const Expr *
expr) {
16260 int AllowOnePastEnd = 0;
16262 expr =
expr->IgnoreParenImpCasts();
16263 switch (
expr->getStmtClass()) {
16264 case Stmt::ArraySubscriptExprClass: {
16267 AllowOnePastEnd > 0);
16271 case Stmt::MemberExprClass: {
16275 case Stmt::CXXMemberCallExprClass: {
16279 case Stmt::ArraySectionExprClass: {
16285 nullptr, AllowOnePastEnd > 0);
16288 case Stmt::UnaryOperatorClass: {
16304 case Stmt::ConditionalOperatorClass: {
16306 if (
const Expr *lhs = cond->
getLHS())
16307 CheckArrayAccess(lhs);
16308 if (
const Expr *rhs = cond->
getRHS())
16309 CheckArrayAccess(rhs);
16312 case Stmt::CXXOperatorCallExprClass: {
16314 for (
const auto *Arg : OCE->arguments())
16315 CheckArrayAccess(Arg);
16325 Expr *RHS,
bool isProperty) {
16337 S.
Diag(Loc, diag::warn_arc_literal_assign)
16339 << (isProperty ? 0 : 1)
16347 Expr *RHS,
bool isProperty) {
16350 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16351 S.
Diag(Loc, diag::warn_arc_retained_assign)
16353 << (isProperty ? 0 : 1)
16357 RHS =
cast->getSubExpr();
16399 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16428 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16429 Diag(Loc, diag::warn_arc_retained_property_assign)
16433 RHS =
cast->getSubExpr();
16456 bool StmtLineInvalid;
16457 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16459 if (StmtLineInvalid)
16462 bool BodyLineInvalid;
16463 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16465 if (BodyLineInvalid)
16469 if (StmtLine != BodyLine)
16484 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16493 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16497 const Stmt *PossibleBody) {
16503 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16504 StmtLoc = FS->getRParenLoc();
16505 Body = FS->getBody();
16506 DiagID = diag::warn_empty_for_body;
16507 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16508 StmtLoc = WS->getRParenLoc();
16509 Body = WS->getBody();
16510 DiagID = diag::warn_empty_while_body;
16515 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16539 if (!ProbableTypo) {
16540 bool BodyColInvalid;
16541 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16543 if (BodyColInvalid)
16546 bool StmtColInvalid;
16549 if (StmtColInvalid)
16552 if (BodyCol > StmtCol)
16553 ProbableTypo =
true;
16556 if (ProbableTypo) {
16558 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16566 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16578 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16580 RHSExpr = CE->
getArg(0);
16581 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16582 CXXSCE && CXXSCE->isXValue())
16583 RHSExpr = CXXSCE->getSubExpr();
16587 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16588 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16591 if (LHSDeclRef && RHSDeclRef) {
16598 auto D =
Diag(OpLoc, diag::warn_self_move)
16614 const Expr *LHSBase = LHSExpr;
16615 const Expr *RHSBase = RHSExpr;
16616 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16617 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16618 if (!LHSME || !RHSME)
16621 while (LHSME && RHSME) {
16628 LHSME = dyn_cast<MemberExpr>(LHSBase);
16629 RHSME = dyn_cast<MemberExpr>(RHSBase);
16632 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16633 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16634 if (LHSDeclRef && RHSDeclRef) {
16641 Diag(OpLoc, diag::warn_self_move)
16648 Diag(OpLoc, diag::warn_self_move)
16672 bool AreUnionMembers =
false) {
16676 assert(((Field1Parent->isStructureOrClassType() &&
16677 Field2Parent->isStructureOrClassType()) ||
16678 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16679 "Can't evaluate layout compatibility between a struct field and a "
16681 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16682 (AreUnionMembers && Field1Parent->isUnionType())) &&
16683 "AreUnionMembers should be 'true' for union fields (only).");
16697 if (Bits1 != Bits2)
16701 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16702 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16705 if (!AreUnionMembers &&
16717 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16718 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16720 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16721 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16726 return isLayoutCompatible(C, F1, F2);
16737 for (
auto *Field1 : RD1->
fields()) {
16738 auto It = llvm::find_if(UnmatchedFields, [&](
const FieldDecl *Field2) {
16741 if (It == UnmatchedFields.end())
16743 [[maybe_unused]]
bool Result = UnmatchedFields.erase(*It);
16747 return UnmatchedFields.empty();
16773 if (
C.hasSameType(T1, T2))
16782 if (TC1 == Type::Enum)
16784 if (TC1 == Type::Record) {
16803 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16834 const ValueDecl **VD, uint64_t *MagicValue,
16835 bool isConstantEvaluated) {
16843 case Stmt::UnaryOperatorClass: {
16852 case Stmt::DeclRefExprClass: {
16858 case Stmt::IntegerLiteralClass: {
16860 llvm::APInt MagicValueAPInt = IL->
getValue();
16861 if (MagicValueAPInt.getActiveBits() <= 64) {
16862 *MagicValue = MagicValueAPInt.getZExtValue();
16868 case Stmt::BinaryConditionalOperatorClass:
16869 case Stmt::ConditionalOperatorClass: {
16874 isConstantEvaluated)) {
16884 case Stmt::BinaryOperatorClass: {
16887 TypeExpr = BO->
getRHS();
16917 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16920 bool isConstantEvaluated) {
16921 FoundWrongKind =
false;
16926 uint64_t MagicValue;
16928 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16932 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16933 if (I->getArgumentKind() != ArgumentKind) {
16934 FoundWrongKind =
true;
16937 TypeInfo.Type = I->getMatchingCType();
16938 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16939 TypeInfo.MustBeNull = I->getMustBeNull();
16950 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16951 if (I == MagicValues->end())
16960 bool LayoutCompatible,
16962 if (!TypeTagForDatatypeMagicValues)
16963 TypeTagForDatatypeMagicValues.reset(
16964 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16967 (*TypeTagForDatatypeMagicValues)[Magic] =
16983 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16984 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16985 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16986 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16989void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16992 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16993 bool IsPointerAttr = Attr->getIsPointer();
16996 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16997 if (TypeTagIdxAST >= ExprArgs.size()) {
16998 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16999 << 0 << Attr->getTypeTagIdx().getSourceIndex();
17002 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
17003 bool FoundWrongKind;
17006 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
17008 if (FoundWrongKind)
17010 diag::warn_type_tag_for_datatype_wrong_kind)
17016 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
17017 if (ArgumentIdxAST >= ExprArgs.size()) {
17018 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
17019 << 1 << Attr->getArgumentIdx().getSourceIndex();
17022 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
17023 if (IsPointerAttr) {
17025 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
17026 if (ICE->getType()->isVoidPointerType() &&
17027 ICE->getCastKind() == CK_BitCast)
17028 ArgumentExpr = ICE->getSubExpr();
17030 QualType ArgumentType = ArgumentExpr->
getType();
17036 if (TypeInfo.MustBeNull) {
17041 diag::warn_type_safety_null_pointer_required)
17049 QualType RequiredType = TypeInfo.Type;
17051 RequiredType =
Context.getPointerType(RequiredType);
17053 bool mismatch =
false;
17054 if (!TypeInfo.LayoutCompatible) {
17055 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
17076 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
17077 << ArgumentType << ArgumentKind
17078 << TypeInfo.LayoutCompatible << RequiredType
17096 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
17104 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
17110 auto &MisalignedMembersForExpr =
17112 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
17113 if (MA != MisalignedMembersForExpr.end() &&
17114 (
T->isDependentType() ||
T->isIntegerType() ||
17115 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
17117 T->getPointeeType()) <= MA->Alignment))))
17118 MisalignedMembersForExpr.erase(MA);
17127 const auto *ME = dyn_cast<MemberExpr>(E);
17139 bool AnyIsPacked =
false;
17141 QualType BaseType = ME->getBase()->getType();
17142 if (BaseType->isDependentType())
17146 auto *RD = BaseType->castAsRecordDecl();
17151 auto *FD = dyn_cast<FieldDecl>(MD);
17157 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
17158 ReverseMemberChain.push_back(FD);
17161 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
17163 assert(TopME &&
"We did not compute a topmost MemberExpr!");
17170 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
17181 if (ExpectedAlignment.
isOne())
17186 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
17187 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
17191 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
17195 if (DRE && !TopME->
isArrow()) {
17198 CompleteObjectAlignment =
17199 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
17203 if (!Offset.isMultipleOf(ExpectedAlignment) ||
17206 CompleteObjectAlignment < ExpectedAlignment) {
17217 for (
FieldDecl *FDI : ReverseMemberChain) {
17218 if (FDI->hasAttr<PackedAttr>() ||
17219 FDI->getParent()->hasAttr<PackedAttr>()) {
17221 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
17227 assert(FD &&
"We did not find a packed FieldDecl!");
17228 Action(E, FD->
getParent(), FD, Alignment);
17232void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
17233 using namespace std::placeholders;
17236 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
17260bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
17261 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
17288 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
17305 assert(!Args.empty() &&
"Should have at least one argument.");
17307 Expr *Arg0 = Args.front();
17310 auto EmitError = [&](
Expr *ArgI) {
17312 diag::err_typecheck_call_different_arg_types)
17313 << Arg0->
getType() << ArgI->getType();
17318 for (
Expr *ArgI : Args.drop_front())
17329 for (
Expr *ArgI : Args.drop_front()) {
17330 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17333 VecI->getElementType()) ||
17334 Vec0->getNumElements() != VecI->getNumElements()) {
17343std::optional<QualType>
17347 return std::nullopt;
17351 return std::nullopt;
17354 for (
int I = 0; I < 2; ++I) {
17358 return std::nullopt;
17359 Args[I] = Converted.
get();
17366 return std::nullopt;
17369 return std::nullopt;
17371 TheCall->
setArg(0, Args[0]);
17372 TheCall->
setArg(1, Args[1]);
17383 TheCall->
getArg(1), Loc) ||
17385 TheCall->
getArg(2), Loc))
17389 for (
int I = 0; I < 3; ++I) {
17394 Args[I] = Converted.
get();
17397 int ArgOrdinal = 1;
17398 for (
Expr *Arg : Args) {
17400 ArgTyRestr, ArgOrdinal++))
17407 for (
int I = 0; I < 3; ++I)
17408 TheCall->
setArg(I, Args[I]);
17414bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17426bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17435 diag::err_builtin_invalid_arg_type)
17436 << 1 << 2 << 1 << 1 << TyArg;
17450 Expr *Matrix = MatrixArg.
get();
17452 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17455 << 1 << 3 << 0 << 0
17462 QualType ResultType =
Context.getConstantMatrixType(
17463 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17466 TheCall->
setType(ResultType);
17469 TheCall->
setArg(0, Matrix);
17474static std::optional<unsigned>
17482 uint64_t
Dim =
Value->getZExtValue();
17498 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17500 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17508 unsigned PtrArgIdx = 0;
17509 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17510 Expr *RowsExpr = TheCall->
getArg(1);
17511 Expr *ColumnsExpr = TheCall->
getArg(2);
17512 Expr *StrideExpr = TheCall->
getArg(3);
17514 bool ArgError =
false;
17521 PtrExpr = PtrConv.
get();
17522 TheCall->
setArg(0, PtrExpr);
17529 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17530 QualType ElementTy;
17533 << PtrArgIdx + 1 << 0 << 5 << 0
17537 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17541 << PtrArgIdx + 1 << 0 << 5
17548 auto ApplyArgumentConversions = [
this](Expr *E) {
17557 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17559 RowsExpr = RowsConv.
get();
17560 TheCall->
setArg(1, RowsExpr);
17562 RowsExpr =
nullptr;
17564 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17566 ColumnsExpr = ColumnsConv.
get();
17567 TheCall->
setArg(2, ColumnsExpr);
17569 ColumnsExpr =
nullptr;
17580 std::optional<unsigned> MaybeRows;
17584 std::optional<unsigned> MaybeColumns;
17589 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17592 StrideExpr = StrideConv.
get();
17593 TheCall->
setArg(3, StrideExpr);
17596 if (std::optional<llvm::APSInt>
Value =
17599 if (Stride < *MaybeRows) {
17601 diag::err_builtin_matrix_stride_too_small);
17607 if (ArgError || !MaybeRows || !MaybeColumns)
17611 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17622 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17624 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17632 unsigned PtrArgIdx = 1;
17633 Expr *MatrixExpr = TheCall->
getArg(0);
17634 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17635 Expr *StrideExpr = TheCall->
getArg(2);
17637 bool ArgError =
false;
17643 MatrixExpr = MatrixConv.
get();
17644 TheCall->
setArg(0, MatrixExpr);
17651 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17654 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17662 PtrExpr = PtrConv.
get();
17663 TheCall->
setArg(1, PtrExpr);
17671 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17674 << PtrArgIdx + 1 << 0 << 5 << 0
17678 QualType ElementTy = PtrTy->getPointeeType();
17680 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17685 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17687 diag::err_builtin_matrix_pointer_arg_mismatch)
17688 << ElementTy << MatrixTy->getElementType();
17703 StrideExpr = StrideConv.
get();
17704 TheCall->
setArg(2, StrideExpr);
17709 if (std::optional<llvm::APSInt>
Value =
17712 if (Stride < MatrixTy->getNumRows()) {
17714 diag::err_builtin_matrix_stride_too_small);
17734 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17739 llvm::StringSet<> CalleeTCBs;
17740 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17741 CalleeTCBs.insert(A->getTCBName());
17742 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17743 CalleeTCBs.insert(A->getTCBName());
17747 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17748 StringRef CallerTCB = A->getTCBName();
17749 if (CalleeTCBs.count(CallerTCB) == 0) {
17750 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17751 << 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 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)
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
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
llvm::SmallString< 64 > 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
This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
bool isOne() const
Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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
Returns true if this DeclContext is a function, Objective-C method, or block, or a DeclContext that c...
DeclContext * getEnclosingNonExpansionStatementContext()
Retrieve the innermost enclosing context that doesn't belong to an expansion statement.
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(const TargetInfo &TI, 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 convertArgumentToType(Expr *&Value, QualType Ty)
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
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 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
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 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
const clang::Expr * ExprTy
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)
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
unsigned getFunctionOrMethodNumParams(const Decl *D, bool IncludeThis=false)
getFunctionOrMethodNumParams - Return number of function or method parameters, optionally including t...
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
unsigned 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.