Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ Moved checkers

Sanitizers
----------
- Improved documentation for legacy ``no_sanitize`` attributes.

Python Binding Changes
----------------------
Expand Down
29 changes: 22 additions & 7 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3921,16 +3921,31 @@ def NoSanitize : InheritableAttr {
}];
}

// Attributes to disable a specific sanitizer. No new sanitizers should be added
// Attribute to disable AddressSanitizer. No new spellings should be added
// to this list; the no_sanitize attribute should be extended instead.
def NoSanitizeSpecific : InheritableAttr {
def NoSanitizeAddress : InheritableAttr {
let Spellings = [GCC<"no_address_safety_analysis">,
GCC<"no_sanitize_address">,
GCC<"no_sanitize_thread">,
Clang<"no_sanitize_memory">];
GCC<"no_sanitize_address">];
let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>;
let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs,
NoSanitizeMemoryDocs];
let Documentation = [NoSanitizeAddressDocs];
let ASTNode = 0;
}

// Attribute to disable ThreadSanitizer. No new spellings should be added
// to this list; the no_sanitize attribute should be extended instead.
def NoSanitizeThread : InheritableAttr {
let Spellings = [GCC<"no_sanitize_thread">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeThreadDocs];
let ASTNode = 0;
}

// Attribute to disable MemorySanitizer. No new spellings should be added
// to this list; the no_sanitize attribute should be extended instead.
def NoSanitizeMemory : InheritableAttr {
let Spellings = [Clang<"no_sanitize_memory">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [NoSanitizeMemoryDocs];
let ASTNode = 0;
}

Expand Down
11 changes: 6 additions & 5 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
// version control.
//
// To run clang-tblgen to generate the .rst file:
// clang-tblgen -gen-attr-docs -I <root>/llvm/tools/clang/include
// <root>/llvm/tools/clang/include/clang/Basic/Attr.td -o
// <root>/llvm/tools/clang/docs/AttributeReference.rst
// clang-tblgen -gen-attr-docs -I <root>/clang/include
// <root>/clang/include/clang/Basic/Attr.td -o
// <root>/clang/docs/AttributeReference.rst
//
// To run sphinx to generate the .html files (note that sphinx-build must be
// available on the PATH):
// Windows (from within the clang\docs directory):
// make.bat html
// Non-Windows (from within the clang\docs directory):
// sphinx-build -b html _build/html
// Non-Windows (from within the clang/docs directory):
// sphinx-build -b html . _build/html

def GlobalDocumentation {
code Intro =[{..
Expand Down Expand Up @@ -3629,6 +3629,7 @@ instrumentations should not be applied.

The attribute takes a list of string literals with the following accepted
values:

* all values accepted by ``-fno-sanitize=``;
* ``coverage``, to disable SanitizerCoverage instrumentation.

Expand Down
50 changes: 33 additions & 17 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6361,19 +6361,8 @@ static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
Sanitizers.size()));
}

static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
StringRef AttrName = AL.getAttrName()->getName();
normalizeName(AttrName);
StringRef SanitizerName = llvm::StringSwitch<StringRef>(AttrName)
.Case("no_address_safety_analysis", "address")
.Case("no_sanitize_address", "address")
.Case("no_sanitize_thread", "thread")
.Case("no_sanitize_memory", "memory");
if (isGlobalVar(D) && SanitizerName != "address")
S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
<< AL << AL.isRegularKeywordAttribute() << ExpectedFunction;

static AttributeCommonInfo
getNoSanitizeAttrInfo(const ParsedAttr &NoSanitizeSpecificAttr) {
// FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
// NoSanitizeAttr object; but we need to calculate the correct spelling list
// index rather than incorrectly assume the index for NoSanitizeSpecificAttr
Expand All @@ -6383,11 +6372,32 @@ static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
// getSpelling() or prettyPrint() on the resulting semantic attribute object
// without failing assertions.
unsigned TranslatedSpellingIndex = 0;
if (AL.isStandardAttributeSyntax())
if (NoSanitizeSpecificAttr.isStandardAttributeSyntax())
TranslatedSpellingIndex = 1;

AttributeCommonInfo Info = AL;
AttributeCommonInfo Info = NoSanitizeSpecificAttr;
Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
return Info;
}

static void handleNoSanitizeAddressAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
StringRef SanitizerName = "address";
AttributeCommonInfo Info = getNoSanitizeAttrInfo(AL);
D->addAttr(::new (S.Context)
NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
}

static void handleNoSanitizeThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
StringRef SanitizerName = "thread";
AttributeCommonInfo Info = getNoSanitizeAttrInfo(AL);
D->addAttr(::new (S.Context)
NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
}

static void handleNoSanitizeMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
StringRef SanitizerName = "memory";
AttributeCommonInfo Info = getNoSanitizeAttrInfo(AL);
D->addAttr(::new (S.Context)
NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
}
Expand Down Expand Up @@ -7513,8 +7523,14 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_NoSanitize:
handleNoSanitizeAttr(S, D, AL);
break;
case ParsedAttr::AT_NoSanitizeSpecific:
handleNoSanitizeSpecificAttr(S, D, AL);
case ParsedAttr::AT_NoSanitizeAddress:
handleNoSanitizeAddressAttr(S, D, AL);
break;
case ParsedAttr::AT_NoSanitizeThread:
handleNoSanitizeThreadAttr(S, D, AL);
break;
case ParsedAttr::AT_NoSanitizeMemory:
handleNoSanitizeMemoryAttr(S, D, AL);
break;
case ParsedAttr::AT_GuardedBy:
handleGuardedByAttr(S, D, AL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@
// CHECK-NEXT: NoProfileFunction (SubjectMatchRule_function)
// CHECK-NEXT: NoRandomizeLayout (SubjectMatchRule_record)
// CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSanitizeAddress (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSanitizeMemory (SubjectMatchRule_function)
// CHECK-NEXT: NoSanitizeThread (SubjectMatchRule_function)
// CHECK-NEXT: NoSpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: NoSplitStack (SubjectMatchRule_function)
// CHECK-NEXT: NoStackProtector (SubjectMatchRule_function)
Expand Down