This is an archive of the discontinued LLVM Phabricator instance.

[Sema] Diagnose more cases of static data members in local or unnamed classes
ClosedPublic

Authored by john.brawn on May 20 2020, 6:46 AM.

Details

Summary

We currently diagnose static data members directly contained in unnamed classes, but we should also diagnose when they're in a class that is nested (directly or indirectly) in an unnamed class. Do this by iterating up the list of parent DeclContexts and checking if any is an unnamed class.

Similarly also check for function or method DeclContexts (which includes things like blocks and openmp captured statements) as then the class is considered to be a local class, which means static data members aren't allowed.

Diff Detail

Event Timeline

john.brawn created this revision.May 20 2020, 6:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 20 2020, 6:46 AM

Adjusted to not give multiple errors when more than one error criteria is met.

rjmccall added inline comments.May 20 2020, 11:22 PM
clang/lib/Sema/SemaDecl.cpp
6916

This diagnostic actually ignores the tag kind that passed down to it, which should be fixed. Also, you should pass in the tag kind for the actual anonymous class you found.

While I'm looking at this code: isLocalClass is mis-designed and doesn't work for any of our non-FunctionDecl local contexts. This check should be if (RD->getParentFunctionOrMethod()).

john.brawn marked an inline comment as done.

Use the tag of the anonymous struct when emitting a diagnostic.

john.brawn added inline comments.May 21 2020, 6:58 AM
clang/lib/Sema/SemaDecl.cpp
6916

This diagnostic actually ignores the tag kind that passed down to it, which should be fixed. Also, you should pass in the tag kind for the actual anonymous class you found.

Will do.

While I'm looking at this code: isLocalClass is mis-designed and doesn't work for any of our non-FunctionDecl local contexts. This check should be if (RD->getParentFunctionOrMethod()).

CXXMethodDecl has FunctionDecl as a parent class, so isLocalClass will find and return a CXXMethodDecl. Checking it on

class Example {
  void method() {
    class X {
      static int x;
    };
  }
};

I get the error as expected. Do you have an example where it doesn't work?

rjmccall added inline comments.May 21 2020, 9:46 AM
clang/lib/Sema/SemaDecl.cpp
6916

Will do.

You need to also update the diagnostic to actually care about this.

Do you have an example where it doesn't work?

All of the standard C/C++ local contexts are FunctionDecls, but "blocks", ObjC methods, and OpenMP captured statements aren't. The simplest example would be (under -fblocks):

void test() {
  ^{
    class X {
      static int x;
    };
  }();
}
john.brawn retitled this revision from [Sema] Diagnose static data members in classes nested in unnamed classes to [Sema] Diagnose more cases of static data members in local or unnamed classes.
john.brawn edited the summary of this revision. (Show Details)

Detect more kinds of local class.

john.brawn marked an inline comment as done.May 22 2020, 11:45 AM
john.brawn added inline comments.
clang/lib/Sema/SemaDecl.cpp
6916

You need to also update the diagnostic to actually care about this.

It looks like it already does? E.g. in the tests added to anonymous-struct.cpp where the error is "anonymous struct" or "anonymous class" depending on if it's an anonymous class or struct.

rjmccall accepted this revision.May 22 2020, 11:52 AM

Thanks, looks great.

clang/lib/Sema/SemaDecl.cpp
6916

Oh, sorry, I just misread the diagnostic.

This revision is now accepted and ready to land.May 22 2020, 11:52 AM
This revision was automatically updated to reflect the committed changes.