diff --git a/clang/include/clang/Basic/NoSanitizeList.h b/clang/include/clang/Basic/NoSanitizeList.h --- a/clang/include/clang/Basic/NoSanitizeList.h +++ b/clang/include/clang/Basic/NoSanitizeList.h @@ -38,7 +38,8 @@ StringRef Category = StringRef()) const; bool containsType(SanitizerMask Mask, StringRef MangledTypeName, StringRef Category = StringRef()) const; - bool containsFunction(SanitizerMask Mask, StringRef FunctionName) const; + bool containsFunction(SanitizerMask Mask, StringRef FunctionName, + StringRef Category = StringRef()) const; bool containsFile(SanitizerMask Mask, StringRef FileName, StringRef Category = StringRef()) const; bool containsLocation(SanitizerMask Mask, SourceLocation Loc, diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp --- a/clang/lib/Basic/NoSanitizeList.cpp +++ b/clang/lib/Basic/NoSanitizeList.cpp @@ -38,8 +38,10 @@ } bool NoSanitizeList::containsFunction(SanitizerMask Mask, - StringRef FunctionName) const { - return SSCL->inSection(Mask, "fun", FunctionName); + StringRef FunctionName, + StringRef Category) const { + + return SSCL->inSection(Mask, "fun", FunctionName, Category); } bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName, diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2234,6 +2234,12 @@ HasStrictReturn &= !VDecl->isExternC(); } + bool EnableNoundefAttrs = + CodeGenOpts.EnableNoundefAttrs && + !(getLangOpts().Sanitize.has(SanitizerKind::Memory) && + isInNoSanitizeList(SanitizerKind::Memory, Name, + /* "by location" is not supported */ {}, "noundef")); + // We don't want to be too aggressive with the return checking, unless // it's explicit in the code opts or we're using an appropriate sanitizer. // Try to respect what the programmer intended. @@ -2243,7 +2249,7 @@ getLangOpts().Sanitize.has(SanitizerKind::Return); // Determine if the return type could be partially undef - if (CodeGenOpts.EnableNoundefAttrs && HasStrictReturn) { + if (EnableNoundefAttrs && HasStrictReturn) { if (!RetTy->isVoidType() && RetAI.getKind() != ABIArgInfo::Indirect && DetermineNoUndef(RetTy, getTypes(), DL, RetAI)) RetAttrs.addAttribute(llvm::Attribute::NoUndef); @@ -2377,8 +2383,7 @@ } // Decide whether the argument we're handling could be partially undef - bool ArgNoUndef = DetermineNoUndef(ParamType, getTypes(), DL, AI); - if (CodeGenOpts.EnableNoundefAttrs && ArgNoUndef) + if (EnableNoundefAttrs && DetermineNoUndef(ParamType, getTypes(), DL, AI)) Attrs.addAttribute(llvm::Attribute::NoUndef); // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -441,43 +441,43 @@ Fn->setDoesNotThrow(); if (getLangOpts().Sanitize.has(SanitizerKind::Address) && - !isInNoSanitizeList(SanitizerKind::Address, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::Address, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeAddress); if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) && - !isInNoSanitizeList(SanitizerKind::KernelAddress, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::KernelAddress, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeAddress); if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) && - !isInNoSanitizeList(SanitizerKind::HWAddress, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::HWAddress, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); if (getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) && - !isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); if (getLangOpts().Sanitize.has(SanitizerKind::MemTag) && - !isInNoSanitizeList(SanitizerKind::MemTag, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::MemTag, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && - !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::Thread, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeThread); if (getLangOpts().Sanitize.has(SanitizerKind::Memory) && - !isInNoSanitizeList(SanitizerKind::Memory, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::Memory, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeMemory); if (getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) && - !isInNoSanitizeList(SanitizerKind::KernelMemory, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::KernelMemory, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SanitizeMemory); if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) && - !isInNoSanitizeList(SanitizerKind::SafeStack, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::SafeStack, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::SafeStack); if (getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) && - !isInNoSanitizeList(SanitizerKind::ShadowCallStack, Fn, Loc)) + !isInNoSanitizeList(SanitizerKind::ShadowCallStack, Fn->getName(), Loc)) Fn->addFnAttr(llvm::Attribute::ShadowCallStack); return Fn; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -734,7 +734,7 @@ if (SanOpts.empty()) \ break; \ if (SanOpts.has(SanitizerKind::ID)) \ - if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \ + if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn->getName(), Loc)) \ SanOpts.set(SanitizerKind::ID, false); #include "clang/Basic/Sanitizers.def" diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1301,8 +1301,9 @@ /// annotations are emitted during finalization of the LLVM code. void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); - bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, - SourceLocation Loc) const; + bool isInNoSanitizeList(SanitizerMask Kind, StringRef FunctionName, + SourceLocation Loc, + StringRef Category = StringRef()) const; bool isInNoSanitizeList(llvm::GlobalVariable *GV, SourceLocation Loc, QualType Ty, StringRef Category = StringRef()) const; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -45,6 +45,7 @@ #include "clang/Basic/Version.h" #include "clang/CodeGen/ConstantInitBuilder.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/TargetLibraryInfo.h" @@ -2667,20 +2668,22 @@ Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation())); } -bool CodeGenModule::isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, - SourceLocation Loc) const { +bool CodeGenModule::isInNoSanitizeList(SanitizerMask Kind, + StringRef FunctionName, + SourceLocation Loc, + StringRef Category) const { const auto &NoSanitizeL = getContext().getNoSanitizeList(); // NoSanitize by function name. - if (NoSanitizeL.containsFunction(Kind, Fn->getName())) + if (NoSanitizeL.containsFunction(Kind, FunctionName, Category)) return true; // NoSanitize by location. if (Loc.isValid()) - return NoSanitizeL.containsLocation(Kind, Loc); + return NoSanitizeL.containsLocation(Kind, Loc, Category); // If location is unknown, this may be a compiler-generated function. Assume // it's located in the main file. auto &SM = Context.getSourceManager(); if (const auto *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { - return NoSanitizeL.containsFile(Kind, MainFile->getName()); + return NoSanitizeL.containsFile(Kind, MainFile->getName(), Category); } return false; } diff --git a/clang/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt b/clang/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt --- a/clang/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt +++ b/clang/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt @@ -2,3 +2,6 @@ fun:*cfi* [cfi] fun:*overflow* +[memory] +fun:*ret_ignored*=noundef +fun:*pass_ignored*=noundef