Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
----------
- Fixed 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
Loading