dexonsmith added inline comments.

================
Comment at: clang/test/Sema/pragma-attribute-label.c:15
+// Out of order!
+#pragma clang attribute pop MY_LABEL
+
----------------
aaron.ballman wrote:
> dexonsmith wrote:
> > erik.pilkington wrote:
> > > aaron.ballman wrote:
> > > > dexonsmith wrote:
> > > > > aaron.ballman wrote:
> > > > > > I feel like this should be diagnosed, perhaps even as an error. The 
> > > > > > user provided labels but then got the push and pop order wrong when 
> > > > > > explicitly saying what to pop. That seems more likely to be a logic 
> > > > > > error on the user's part.
> > > > > On the contrary, the user is using two differently-named and 
> > > > > independent macro pairs (A_BEGIN/A_END vs B_BEGIN/B_END) and has no 
> > > > > idea they are implemented with _Pragma(“clang attribute ...”) under 
> > > > > the hood.  The point is to give the same result as two independent 
> > > > > pragma pairs, whose regions do not need to be nested.
> > > > > On the contrary, the user is using two differently-named and 
> > > > > independent macro pairs (A_BEGIN/A_END vs B_BEGIN/B_END) 
> > > > 
> > > > I don't think this is a safe assumption to make, and in this case, is 
> > > > false. There are no macros anywhere in this test case.
> > > > 
> > > > > The point is to give the same result as two independent pragma pairs, 
> > > > > whose regions do not need to be nested.
> > > > 
> > > > I don't find this to be intuitive behavior. These are stack 
> > > > manipulations with the names push and pop -- pretending that they're 
> > > > overlapping rather than a stack in the presence of labels is confusing. 
> > > > If I saw the code from this test case during a code review, I would 
> > > > flag it as being incorrect because the labels do not match -- I don't 
> > > > think I'd be the only one.
> > > I think the labels only really makes sense if you're writing macros that 
> > > hide the pragma attribute stack (like ASSUME_X_BEGIN/END, for instance), 
> > > which for better or for worse people do write, and in fact was the 
> > > intended use case for #pragma clang attribute. I think if we were to 
> > > write this feature again, we'd forgo the stack entirly and require every 
> > > `push` to have a label and be in its own namespace. But this is the best 
> > > we can do now.
> > > 
> > > I don't really think that anyone should write a push label outside of a 
> > > macro definition, since I agree that the semantics are a bit surprising 
> > > when you're writing the #pragmas yourself without macros. I'll update 
> > > this test case and the documentation to stress this point more. If you 
> > > think this is going to be a potential pain point, maybe we can even warn 
> > > on using a label outside of a macro definition. 
> > >> The point is to give the same result as two independent pragma pairs, 
> > >> whose regions do not need to be nested.
> > > I don't find this to be intuitive behavior. These are stack manipulations 
> > > with the names push and pop -- pretending that they're overlapping rather 
> > > than a stack in the presence of labels is confusing. If I saw the code 
> > > from this test case during a code review, I would flag it as being 
> > > incorrect because the labels do not match -- I don't think I'd be the 
> > > only one.
> > 
> > As Erik says, the intention is that these are only used by macros.
> > 
> > Stepping back, the goal of this pragma (which we added in 
> > https://reviews.llvm.org/D30009) is to avoid adding a new region-based 
> > pragma every time we want to apply an attribute within a region.  Clang has 
> > a lot of these pragmas, in order to support independent macros like this:
> > ```
> > #define A_BEGIN _Pragma("clang a push")
> > #define A_END   _Pragma("clang a pop")
> > #define B_BEGIN _Pragma("clang b push")
> > #define B_END   _Pragma("clang b pop")
> > #define C_BEGIN _Pragma("clang c push")
> > #define C_END   _Pragma("clang c pop")
> > ```
> > 
> > @arphaman came up with the idea of introduce "one pragma to rule them all", 
> > `pragma clang attribute`, so that we didn't need to introduce a new pragma 
> > each time we wanted an independent region:
> > ```
> > #define A_BEGIN _Pragma("clang attribute push(a)")
> > #define A_END   _Pragma("clang attribute pop")
> > #define B_BEGIN _Pragma("clang attribute push(b)")
> > #define B_END   _Pragma("clang attribute pop")
> > #define C_BEGIN _Pragma("clang attribute push(c)")
> > #define C_END   _Pragma("clang attribute pop")
> > ```
> > 
> > However, we've realized that there is a major design flaw: these macros are 
> > not independent, because they're using the same stack.  @erik.pilkington 
> > has come up with this solution using identifiers to namespace the attribute 
> > stacks, allowing the macros to be independent (like they were before, when 
> > each had a dedicated pragma):
> > ```
> > #define A_BEGIN _Pragma("clang attribute push A (a)")
> > #define A_END   _Pragma("clang attribute pop  A")
> > #define B_BEGIN _Pragma("clang attribute push B (b)")
> > #define B_END   _Pragma("clang attribute pop  B")
> > #define C_BEGIN _Pragma("clang attribute push C (c)")
> > #define C_END   _Pragma("clang attribute pop  C")
> > ```
> > 
> > To be clear, without this behaviour (or something equivalent) `#pragma 
> > clang attribute` is completely broken for its motivating use case.  If we 
> > can't find a design that allows us to interleave these macros, we will have 
> > to abandon this pragma entirely (and go back to adding a significant number 
> > of dedicated one-off pragmas).
> > 
> > But it's the behaviour we care about, not this particular syntax.  Since 
> > this pragma is designed specifically to be hidden behind macros, it can be 
> > as ugly as you want.  Is there another way of spelling this that you find 
> > more intuitive?  Or should we just improve the docs as Erik has done?
> > As Erik says, the intention is that these are only used by macros.
> 
> That's a nice intention, but that doesn't mean all users are going to do 
> that. I'm worried about the users who don't adhere to that intention and use 
> the pragmas in their more exposed format, given that it's a supported syntax.
> 
> 
> > But it's the behaviour we care about, not this particular syntax. Since 
> > this pragma is designed specifically to be hidden behind macros, it can be 
> > as ugly as you want. 
> 
> I'm not worried about the ugliness, I'm worried about whether it's 
> understandable behavior when the pragma is not hidden behind a macro.
> 
> > Is there another way of spelling this that you find more intuitive? Or 
> > should we just improve the docs as Erik has done?
> 
> @erik.pilkington and I talked over IRC and I have a better understanding of 
> where my disconnect is here. It seems as though push/pop was the incorrect 
> initial design for the feature and what we really wish we had was a 
> region-based approach rather than a stack-based approach. Would it make sense 
> to add `#pragma clang attribute begin/end` syntax with labels instead? Then 
> the macros could switch to using that approach to solve the problems you're 
> running into. We could still have push/pop with labels, but they could warn 
> on label mismatches (which would also help alert users to problems like what 
> is in the summary for this patch) instead of treating it as a region.
Sounds great; thanks Aaron.

Another idea I had over lunch was `#pragma clang attribute IDENTIFIER 
push/pop`, making it clear that each identifier has an independent stack.


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

https://reviews.llvm.org/D55628



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to