[clang] nolock/noalloc attributes (PR #84983)
Doug Wyatt via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 13 07:36:38 PDT 2024
================
@@ -4912,3 +4922,279 @@ void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
getTypeConstraintConcept(), getTypeConstraintArguments());
}
+
+FunctionEffect::~FunctionEffect() = default;
+
+bool FunctionEffect::diagnoseConversion(bool Adding, QualType OldType,
+ FunctionEffectSet OldFX,
+ QualType NewType,
+ FunctionEffectSet NewFX) const {
+ return false;
+}
+
+bool FunctionEffect::diagnoseRedeclaration(bool Adding,
+ const FunctionDecl &OldFunction,
+ FunctionEffectSet OldFX,
+ const FunctionDecl &NewFunction,
+ FunctionEffectSet NewFX) const {
+ return false;
+}
+
+bool FunctionEffect::diagnoseMethodOverride(bool Adding,
+ const CXXMethodDecl &OldMethod,
+ FunctionEffectSet OldFX,
+ const CXXMethodDecl &NewMethod,
+ FunctionEffectSet NewFX) const {
+ return false;
+}
+
+bool FunctionEffect::canInferOnDecl(const Decl *Caller,
+ FunctionEffectSet CallerFX) const {
+ return false;
+}
+
+bool FunctionEffect::diagnoseFunctionCall(bool Direct, const Decl *Caller,
+ FunctionEffectSet CallerFX,
+ CalleeDeclOrType Callee,
+ FunctionEffectSet CalleeFX) const {
+ return false;
+}
+
+const NoLockNoAllocEffect &NoLockNoAllocEffect::nolock_instance() {
+ static NoLockNoAllocEffect global(kNoLockTrue, "nolock");
+ return global;
+}
----------------
dougsonos wrote:
The GNU syntax is more liberal, and yes, this is supported (and tested as of my next push):
```
// Alternate placement on the FunctionDecl
__attribute__((clang_nolock)) void nl_function();
// CHECK: FunctionDecl {{.*}} nl_function 'void () __attribute__((clang_nolock))'
```
One reason I prefer the square-bracket syntax is that it is not only consistent with `noexcept`, but it becomes practical to apply both `nolock` and `noexcept` with a single macro (not sure yet I want to do that to my codebase, but it's possible).
Another is that the placement rules seem more consistent and sensible, to me anyhow.
The `nolock/noalloc(true)` attributes do need to apply to function types, not declarations, so as to be able to analyze indirect calls. They only applies to declarations as a consequence of declarations having function types. `nolock/noalloc(false)` have to be treated the same way as the `true` form for parsing, but for analysis purposes, they end up being ignored until they land on a `Decl`, since indirect calls prevent inference regardless.
As for the rule about square brackets, in SemaType.cpp:
```
FUNCTION_TYPE_ATTRS_CASELIST:
attr.setUsedAsTypeAttr();
// Attributes with standard syntax have strict rules for what they
// appertain to and hence should not use the "distribution" logic below.
if (attr.isStandardAttributeSyntax() ||
attr.isRegularKeywordAttribute()) {
if (!handleFunctionTypeAttr(state, attr, type, CFT)) {
diagnoseBadTypeAttribute(state.getSema(), attr, type);
attr.setInvalid();
}
break;
}
```
So with square-bracket syntax, the attribute has to follow the right parenthesis enclosing the parameter list (and after const).
Incidentally, I realized that in Attr.td the attributes can derive from `TypeAttr` rather than `DeclOrTypeAttr`.
https://github.com/llvm/llvm-project/pull/84983
More information about the cfe-commits
mailing list