[PATCH] D79121: Add nomerge function attribute to clang

Reid Kleckner via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 30 14:32:58 PDT 2020


rnk added inline comments.


================
Comment at: clang/include/clang/Basic/Attr.td:1799
+  let Spellings = [Clang<"nomerge">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [NoMergeDocs];
----------------
rnk wrote:
> aaron.ballman wrote:
> > zequanwu wrote:
> > > rnk wrote:
> > > > Clang supports many function-like things that are not functions, for example, Objective C method declarations are not considered FunctionDecls in the AST. Blocks are another function-like thing. I see below there is a `FunctionLike` subject type. Lets use that here.
> > > > 
> > > > I would like to make it possible to apply this attribute directly to call expressions as well, but I don't see a good example of how to do that in the existing attribute. I'd like to be able to do this, for example:
> > > > 
> > > > ```
> > > > void __attribute__((noreturn)) bar();
> > > > void foo(bool cond) {
> > > >   if (cond)
> > > >     [[clang::nomerge]] bar();
> > > >   else
> > > >     [[clang::nomerge]] bar();
> > > > }
> > > > ```
> > > > 
> > > > This gives the user fine-grained control. It allows them to call some existing API, like perhaps RaiseException, of which they do not control the declaration, and mark the calls as unmergeable.
> > > It seems like there is no exiting example of call site attributes. https://github.com/llvm/llvm-project/blob/master/clang/lib/CodeGen/CGCall.cpp#L4767. And the function `EmitCall` may not know existence of call site attributes.
> > > I would like to make it possible to apply this attribute directly to call expressions as well, but I don't see a good example of how to do that in the existing attribute.
> > 
> > You would have to use a statement attribute rather than a declaration attribute for this, and we have a few of those but none that work on call expressions specifically.
> > 
> > One question I have about that idea is whether attributes give you fine enough levels of control (I don't know enough about `nomerge` to answer this myself). e.g., `foo(bar(), bar()); // Do you want to nomerge the bar() calls, the foo() call, or all three?` (You can only add the attribute to the statement expression, not to individual expressions.)
> I guess what I really wanted was an expression attribute, so you can put it on the calls to `bar`. :)
> 
> But given that that doesn't exist, I think it would be OK to do either one of the following:
> - Apply nomerge attribute to all call sites in the whole Stmt
> - Apply nomerge only to the first CallExpr found inside the Stmt
> 
> I think the simplest implementation is to, in CodeGenFunction, set a flag (NoMerge) on CodeGenFunction when emitting such an attributed statement with this attribute. Then set it back on exit. Something like that.
It's worth considering some test cases where the call expression is not the top-most AST node in the expression:
```
[[clang::nomerge]] (x = 42, abort());
[[clang::nomerge]] (void)(throwException());
```
We can probably make an ExprWithTemporaries wrapper, ParenExpr wrapper, or others.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79121/new/

https://reviews.llvm.org/D79121





More information about the cfe-commits mailing list