https://github.com/vonosmas updated https://github.com/llvm/llvm-project/pull/161311
>From d6e24fe168efeff4099b0ee83a5a559caa0c7628 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov <[email protected]> Date: Mon, 29 Sep 2025 21:07:25 -0700 Subject: [PATCH 1/2] [clang] Cleanup docs and code for legacy no_sanitize attributes (NFC). 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. --- clang/include/clang/Basic/Attr.td | 29 ++++++++--- clang/include/clang/Basic/AttrDocs.td | 11 ++-- clang/lib/Sema/SemaDeclAttr.cpp | 52 +++++++++++++------ ...a-attribute-supported-attributes-list.test | 4 +- 4 files changed, 66 insertions(+), 30 deletions(-) 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..fceb8f0eda289 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,34 @@ 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 +7525,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) >From c53f3d40c96ecf9737644096e122447e8f93c2cd Mon Sep 17 00:00:00 2001 From: Alexey Samsonov <[email protected]> Date: Mon, 29 Sep 2025 22:28:40 -0700 Subject: [PATCH 2/2] fix clang-format --- clang/lib/Sema/SemaDeclAttr.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index fceb8f0eda289..328ccf6694073 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6388,16 +6388,14 @@ static void handleNoSanitizeAddressAttr(Sema &S, Decl *D, NoSanitizeAttr(S.Context, Info, &SanitizerName, 1)); } -static void handleNoSanitizeThreadAttr(Sema &S, Decl *D, - const ParsedAttr &AL) { +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) { +static void handleNoSanitizeMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) { StringRef SanitizerName = "memory"; AttributeCommonInfo Info = getNoSanitizeAttrInfo(AL); D->addAttr(::new (S.Context) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
