aaron.ballman added inline comments.

================
Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:377
+  "%0 is a reserved identifier">,
+  InGroup<ReservedIdentifier>, DefaultIgnore;
+
----------------
Quuxplusone wrote:
> If you leave it like this, you //will// receive multiple bug reports per year 
> about how in some contexts the compiler diagnoses `_X` and `_x` equally, and 
> in other contexts the compiler diagnoses `_X` but fails to diagnose `_x`.
> 
> You should make two diagnostics: `-Wreserved-extern-identifier` and 
> `-Wreserved-pp-identifier` (or something along those lines), and their 
> messages should be carefully worded to explain //why// the warning is 
> happening — "identifier %0 is reserved for use at file scope," "identifier %0 
> is reserved in all contexts," etc.
> 
> Btw, the reason some identifiers (like `_X`) are reserved in all contexts is 
> so that the implementation can define them as macros (e.g. header guards).
I think splitting the diagnostic into two groups could be useful, but I'd still 
like the groups to be under a common grouping so I can enable/disable all 
reserved identifier warnings at once.

As for adding the extra rationale to the diagnostic message: I think if we want 
to add extra wording, it should be more about how the user can fix the name and 
less about why the standard reserves something. e.g., `"identifier %0 is 
reserved because %select{it starts with '__'|it contains '__'|it is the same 
identifier as a keyword|etc}0"`. Knowing that something is reserved at file 
scope is somewhat helpful, but knowing how to change the name to appease the 
compiler is too.


================
Comment at: clang/lib/AST/Decl.cpp:1096
+    // Walk up the lexical parents to determine if we're at TU level or not.
+    const DeclContext * DC = getLexicalDeclContext();
+    while(DC->isTransparentContext())
----------------
You may want to run the patch through clang-format.


================
Comment at: clang/lib/Sema/SemaDecl.cpp:5554
+  // Avoid warning twice on the same identifier, and don't warn on 
redeclaration
+  // of system decl
+  if (D->getPreviousDecl())
----------------



================
Comment at: clang/lib/Sema/SemaDeclCXX.cpp:10018
   if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
-    for (unsigned i = 0; i < DD->getNumTemplateParameterLists(); ++i)
+    for (unsigned i = 0; i < DD->getNumTemplateParameterLists(); ++i) {
       ParameterLists.push_back(DD->getTemplateParameterList(i));
----------------
Unrelated changes?


================
Comment at: clang/lib/Sema/SemaStmt.cpp:544
 
+  if (!Context.getSourceManager().isInSystemHeader(IdentLoc) &&
+      TheDecl->isReserved(getLangOpts()))
----------------
Can you not call `warnOnReservedIdentifier(TheDecl)` in this case?


================
Comment at: clang/test/Sema/reserved-identifier.c:49-50
+// FIXME: According to clang declaration context layering, _preserved belongs 
to
+// the translation unit, so we emit a warning. It's unclear that's what the
+// standard mandate, but it's such a corner case we can live with it.
+void func(struct _preserved { int a; } r) {} // expected-warning 
{{'_preserved' is a reserved identifier}}
----------------
I think we're correct to warn on this. Because the type specifier appears 
within the parameter list, it has function prototype scope per C2x 6.2.1p4. 
However, the identifier `_preserved` is put into the struct name space, which 
hits the "in the tag name spaces" part of: "All identifiers that begin with an 
underscore are reserved for use as identifiers with file scope in both the 
ordinary and tag name spaces".


================
Comment at: clang/test/Sema/reserved-identifier.c:53
+
+extern char *_strdup(const char *); // expected-warning {{'_strdup' is a 
reserved identifier}}
+
----------------
This is a case I don't think we should warn on. As some examples showing this 
sort of thing in the wild:

https://codesearch.isocpp.org/actcd19/main/m/mcrl2/mcrl2_201409.0-1/3rd-party/svc/source/lz.cpp
https://codesearch.isocpp.org/actcd19/main/m/mcrl2/mcrl2_201409.0-1/3rd-party/svc/source/svc1.cpp


================
Comment at: clang/test/Sema/reserved-identifier.c:9
+int _foo() { return 0; }        // expected-warning {{'_foo' is a reserved 
identifier}}
+
+// This one is explicitly skipped by -Wreserved-identifier
----------------
serge-sans-paille wrote:
> Quuxplusone wrote:
> > aaron.ballman wrote:
> > > Can you add a test that we do not warn on an extern declaration? e.g.,
> > > ```
> > > extern char *_strdup(const char *);
> > > ```
> > > This is sometimes used (esp in older C code bases) to avoid having to 
> > > include an entire header to scrape one declaration out of it, and there 
> > > are popular libraries (like the MSVC CRT) that have APIs starting with a 
> > > single underscore and lowercase letter.
> > > 
> > > The idea here is: if it's an extern declaration, the identifier is 
> > > "owned" by some other declaration and this is not likely something the 
> > > user has control over.
> > Should that logic also apply to a forward declaration like `struct _foo;`? 
> > Should it apply to `struct _foo { int i; };`? These are also things the 
> > user might not have control over. (And they're equally things that the user 
> > //could// pull out into a separate .h file surrounded by disabled-warning 
> > pragmas, if they really wanted to.)
> I'd say 100% yeah to the forward declaration, but I'm unsure about the actual 
> definition, because there's no way to distinguish it from a user definition.
> Should that logic also apply to a forward declaration like `struct _foo;`?

I could see a case for not warning on a forward declaration like that, but I 
think it's a bit less compelling because I can't seem to find that pattern 
happening in the wild like I can for extern function declarations.

> Should it apply to struct _foo { int i; };?

This is a definition of the type and so I think it should be warned on (unless 
it's in a system header).


================
Comment at: clang/test/Sema/reserved-identifier.cpp:77
+
+long double operator"" _BarbeBleue(long double) // no-warning
+{
----------------
Quuxplusone wrote:
> This should get a warning, since it's using an identifier "reserved for any 
> use."
> https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier
> http://eel.is/c++draft/lex.name#3.1
> If the implementation predefines `#define _BarbeBleue 42` (which the 
> implementation is permitted to do), then this code won't compile.
+1, this really is reserved.


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

https://reviews.llvm.org/D93095

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

Reply via email to