JonasToth added a comment.

> Using regex could be a reasonable way out, but isn't going to solve the 
> problem in general because not all of the macro names are ones the user has 
> control over. Having to whitelist dozens of macros by name means this check 
> is simply going to be disabled by the user as being low-value.

Yes. I think with the regex its exactly implemented like the rules say. But 
adding sugar is still reasonable. I will run the check over llvm to get a 
feeling how much is still left after silence `LLVM_*` and others that are 
clearly scoped.

> Except that's not the only form of conditional compilation I'm worried about. 
> See Compiler.h where we do things like `#define __has_attribute(x) 0`, which 
> is a perfectly reasonable macro to define (and is an example of a macro name 
> outside of the user's control, so they cannot simply prefix it for a 
> whitelist).

Having a regex allows to add `__has_attribute` to it or a pattern like 
`__has*`. But how many cases for such macros are left? The goal of the 
guidelines is to change coding style and requiring to silence _SOME_ warnings 
is reasonable to me.

> However, I have no idea how we would handle cases like LLVM_LIKELY and 
> LLVM_UNLIKELY, but expecting users to NOLINT 500+ lines of common macro code 
> doesn't seem like a good first approach. I'd be curious to know what the C++ 
> Core Guidelines folks think about those use cases and how they would 
> recommend rewriting the code to adhere to their guidelines. Do they really 
> expect users to use *no* macros in C++ code outside of header include guards 
> and noop definitions even when asked about reasonable use cases like 
> cross-compiler attributes or builtins? I mean, many of these things cannot 
> even use the attribute the C++ Core Guidelines require for silencing such 
> diagnostics -- how do they want to use gsl::suppress to silence a diagnostic 
> on a macro definition?

I think the long term goal is removing the preprocessor, but especially 
compiler specifics are very unlikely to get away soon. 
They themself make exceptions: ES.33: If you must use macros, give them unique 
names 
<https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es33-if-you-must-use-macros-give-them-unique-names>

>> 2. Compiler intrinsics These are similar to attributes and could maybe even 
>> treated the same.
> 
> I'm less certain about this one -- with attributes, there's syntax that we 
> can inspect (is there an `__attribute__` or `__declspec` keyword?), but with 
> intrinsics there's no commonality. Or are you thinking of tablegenning the 
> list of intrinsics?

I thought mostly of `__builtin` when proposing. Checking the MSVC docs showed 
that not all compilers do follow such nice naming conventions. Adding a clang 
and gcc list of builtins might still be manageable with basic string handling.
I feel that keeping any list of all compiler intrinsics is too much.

>> 3. Compatibility with older C++ Standards Stuff like `#define OVERRIDE 
>> override` if the code is compiled with C++11 or newer might be acceptable 
>> for stepwise modernization. This can can be considered as program text 
>> manipulation that was explicitly forbidden but does not obscure code so an 
>> exception could be made. Such macros can be detected with string comparisons.
> 
> How would you generalize this? I've seen people use macros for arbitrary 
> keywords (`#define CONST const` and `#define false false`) as well as macros 
> for arbitrary syntax (`#define DEFAULTED {}` or `#define DEFAULTED = 
> default`).

Not sure about all. I think new keywords like `#define OVERRIDE override` 
should definitly be allowed. But things like `false` not, because it already is 
a keyword in C++98.

I am against allowing `#define DEFAULTED` because both are perfectly valid and 
we ship a check for modernizing from one to the other version. This is 
different to `OVERRIDE`, because it adds additional value for the programmer 
who might be stuck at C++98.

>> 4. Debugging/Logging stuff that contains the Line and file. These can not be 
>> modeled with current C++(?), but `LineInfo` or similar exists. I don't know 
>> what its status is. I think it is ok to require manual silencing for such 
>> macros.
> 
> In addition to `__LINE__` and `__FILE__`, I think we want to include 
> `__DATE__`, `__TIME__`, and `__func__`.

Agreed.

> I think this list is a good start, but is likely incomplete. We'll probably 
> discover other things to add to the list when testing the check against other 
> real world code bases to see what patterns emerge from them.

Testing Frameworks are a common source for macro usage too. They should be 
coverable with the regex approach, but I don't know if there are other things 
hidden behind the interface that would be super annoying to silence.
Same for benchmark libraries.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41648



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

Reply via email to