================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits