[clang] 98766d2 - [clang] Cleanup docs and code for legacy no_sanitize attributes (NFC). (#161311)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 30 11:09:06 PDT 2025
Author: Alexey Samsonov
Date: 2025-09-30T11:09:01-07:00
New Revision: 98766d288f0d7cadcf34f355d36e4deaf233d046
URL: https://github.com/llvm/llvm-project/commit/98766d288f0d7cadcf34f355d36e4deaf233d046
DIFF: https://github.com/llvm/llvm-project/commit/98766d288f0d7cadcf34f355d36e4deaf233d046.diff
LOG: [clang] Cleanup docs and code for legacy no_sanitize attributes (NFC). (#161311)
Update generated docs for legacy attributes:
* no_sanitize_(address|thread|memory)
* no_address_safety_analysis
Those are older forms of no_sanitize("list", "of", "sanitizers")
attribute. They were previously as various spellings of the same
attribute, which made the auto-generated documentation confusing.
Fix this by explicitly making them three different attributes. This
would also allow to simplify the delegation to the new no_sanitize form
slightly, as we can instead rely on auto-generated code to check that
TSan and MSan can't be disabled for globals.
**HTML docs before:**
<img width="1004" height="1175" alt="rendered-docs-before"
src="https://github.com/user-attachments/assets/407b5fc1-799c-4882-8ff8-44a5ef3cf4f1"
/>
**HTML docs after:**
<img width="1098" height="1118" alt="rendered-docs-after"
src="https://github.com/user-attachments/assets/236ca93f-25f8-4d58-95ac-ede95ce18d01"
/>
---------
Co-authored-by: Erich Keane <ekeane at nvidia.com>
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Misc/pragma-attribute-supported-attributes-list.test
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3b269ccd57718..97799aeadfc7e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -583,6 +583,7 @@ Moved checkers
Sanitizers
----------
+- Improved documentation for legacy ``no_sanitize`` attributes.
Python Binding Changes
----------------------
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 2623f9ff6972f..de56bb38fd63e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -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;
}
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index ee212a9b50f36..20a52b49a8f10 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -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 =[{..
@@ -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.
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index a8dfa4d7df2d5..328ccf6694073 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -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
@@ -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));
}
@@ -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);
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 37ff33e5a1523..73d4cb1769ed5 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -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)
More information about the cfe-commits
mailing list