This is an archive of the discontinued LLVM Phabricator instance.

Allow 'static' storage specifier on an out-of-line class member template declaration in MSVCCompat mode
ClosedPublic

Authored by Manna on Mar 12 2019, 5:25 PM.

Details

Summary

Microsoft compiler permits the use of "static" specifier on out-of-class member template declaration.

This patch allows 'static' storage specifier on an out-of-line class member template declaration with a warning in Clang (To be compatible with Microsoft).

Intel C++ compiler allows the 'static' keyword with a warning in Microsoft mode. GCC allows this with a warning with -fpermissive.

Diff Detail

Event Timeline

Manna created this revision.Mar 12 2019, 5:25 PM

I feel like I must be missing something, because MSVC does not accept the code from your test case: https://godbolt.org/z/r6evxY Are there other language options required to get MSVC to accept this code, or perhaps is it only accepted by certain versions of MSVC?

lib/Sema/SemaDecl.cpp
8679–8681

Can you reverse the order here so it checks MSVCCompat first?

test/SemaCXX/warn-static-outside-class-definition.cpp
13–16

Formatting is off here, you should run the patch through clang-format.

Manna updated this revision to Diff 194803.Apr 11 2019, 8:51 PM

Patch is updated based on the comments.

Manna marked 2 inline comments as done.Apr 11 2019, 8:54 PM

I feel like I must be missing something, because MSVC does not accept the code from your test case: https://godbolt.org/z/r6evxY Are there other language options required to get MSVC to accept this code, or perhaps is it only accepted by certain versions of MSVC?

Thanks Aaron.

Yes, it seems like I made some mistake during testing. MSVC2013 accepts the code. MSVS2017 and MSVC2019 fails to compile the same code.

aaron.ballman accepted this revision.Apr 15 2019, 1:10 PM

I feel like I must be missing something, because MSVC does not accept the code from your test case: https://godbolt.org/z/r6evxY Are there other language options required to get MSVC to accept this code, or perhaps is it only accepted by certain versions of MSVC?

Thanks Aaron.

Yes, it seems like I made some mistake during testing. MSVC2013 accepts the code. MSVS2017 and MSVC2019 fails to compile the same code.

I double-checked MSVC 2015 and it also does not accept the code. Aside from a testing nit, this LGTM!

test/SemaCXX/warn-static-outside-class-definition.cpp
1–2

You should add a second RUN line and explicitly specify the MSVC versions so that you can test the diagnostic triggering and not triggering, as appropriate.

This revision is now accepted and ready to land.Apr 15 2019, 1:10 PM
Manna updated this revision to Diff 197912.May 2 2019, 7:54 PM

Sorry for replying late. Thanks for the review. I have updated the patch. Lit test gives warning diagnostic in Microsoft mode up to MSVC 2013 and errors in MSVS2015, MSVS2017 and MSVC2019.

Manna marked an inline comment as done.May 2 2019, 7:55 PM
Manna added inline comments.
test/SemaCXX/warn-static-outside-class-definition.cpp
1–2

Fix the issue by updating the patch.

I would still like to see the second RUN line added to the test so we can ensure we don't regress the behavior.

Manna updated this revision to Diff 197973.May 3 2019, 5:58 AM
Manna added a comment.May 3 2019, 6:01 AM

I would still like to see the second RUN line added to the test so we can ensure we don't regress the behavior.

Thanks Aaron. I have added second RUN line and explicitly specify the MSVC versions.

aaron.ballman added inline comments.May 3 2019, 7:26 AM
test/SemaCXX/warn-static-outside-class-definition.cpp
2

This isn't quite what I was after. I was looking for a RUN line with a MS version < MSVC 2015 to test that the diagnostic is not triggered in that case.

Manna updated this revision to Diff 198018.May 3 2019, 8:32 AM

I have added RUN line (-fms-compatibility-version=12.0) with a MS version < MSVC 2015

Manna marked an inline comment as done.May 3 2019, 8:33 AM
aaron.ballman added inline comments.May 3 2019, 10:30 PM
test/SemaCXX/warn-static-outside-class-definition.cpp
2

Something seems amiss here if this test still passes -- I thought one of these RUN lines was going to err and the other was going to warn because the MSVC behavior changed with 2015 for this case?

Manna marked an inline comment as done.May 7 2019, 8:37 AM
Manna added inline comments.
test/SemaCXX/warn-static-outside-class-definition.cpp
2

This is what I notice with the current patches. The test behavior is changing based upon MSVC version changes.

The test is generating errors with MSVC2015, MSVC2017, and MSVC2019 with but warning with MSVC2013 for this case.

//MSVC2013

ksh-3.2$ clang -c test.cpp
test.cpp:8:23: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <typename T> static int C::foo(T) {

^~~~~~~

test.cpp:17:20: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <class T> static void S<T>::f() {

^~~~~~~

2 warnings generated.

ksh-3.2$ cl -v
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.40629 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

cl : Command line warning D9002 : ignoring unknown option '-v'
cl : Command line error D8003 : missing source filename

//MSVC2015
ksh-3.2$ clang -c test.cpp
test.cpp:8:23: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <typename T> static int C::foo(T) {

^~~~~~~

test.cpp:17:20: error: 'static' can only be specified inside the class definition
template <class T> static void S<T>::f() {

^~~~~~~

1 warning and 1 error generated.

ksh-3.2$ cl -v
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

cl : Command line warning D9002 : ignoring unknown option '-v'
cl : Command line error D8003 : missing source filename

//MSVC2017

ksh-3.2$ clang -c test.cpp
test.cpp:8:23: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <typename T> static int C::foo(T) {

^~~~~~~

test.cpp:17:20: error: 'static' can only be specified inside the class definition
template <class T> static void S<T>::f() {

^~~~~~~

1 warning and 1 error generated.

ksh-3.2$ cl -v
Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26726 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

cl : Command line warning D9002 : ignoring unknown option '-v'
cl : Command line error D8003 : missing source filename

//MSVC2019
ksh-3.2$ clang -c test.cpp
test.cpp:8:23: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <typename T> static int C::foo(T) {

^~~~~~~

test.cpp:17:20: error: 'static' can only be specified inside the class definition
template <class T> static void S<T>::f() {

^~~~~~~

1 warning and 1 error generated.

ksh-3.2$ cl -v
Microsoft (R) C/C++ Optimizing Compiler Version 19.20.27508.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

cl : Command line warning D9002 : ignoring unknown option '-v'
cl : Command line error D8003 : missing source filename

aaron.ballman added inline comments.May 7 2019, 8:58 AM
test/SemaCXX/warn-static-outside-class-definition.cpp
2

This behavior points out the issue:

//MSVC2015
ksh-3.2$ clang -c test.cpp
test.cpp:8:23: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <typename T> static int C::foo(T) {

^~~~~~~
test.cpp:17:20: error: 'static' can only be specified inside the class definition
template <class T> static void S<T>::f() {

^~~~~~~
1 warning and 1 error generated.

Your test case currently expects a warning line 17 and not an error, so running this test through lit should fail until you update the comment on line 18. That should be a warning in some modes and an error in others.

Manna updated this revision to Diff 198502.May 7 2019, 11:33 AM

I have updated test.

//MSVC2013

ksh-3.2$ clang -c test.cpp
test.cpp:8:23: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <typename T> static int C::foo(T) {

^~~~~~~

test.cpp:21:20: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <class T> static void S<T>::f() {}

^~~~~~~

2 warnings generated.
//MSVC2015
ksh-3.2$ clang -c test.cpp
test.cpp:8:23: warning: 'static' can only be specified inside the class definition [-Wmicrosoft-template]
template <typename T> static int C::foo(T) {

^~~~~~~

test.cpp:18:20: error: 'static' can only be specified inside the class definition
template <class T> static void S<T>::f() {}

^~~~~~~

1 warning and 1 error generated.

aaron.ballman accepted this revision.May 7 2019, 12:49 PM

Thank you for updating the test! One minor nit with the way the test case is written, but otherwise LGTM.

test/SemaCXX/warn-static-outside-class-definition.cpp
17–23

I'd prefer to see this written as:

template <class T> static void S<T>::f() {}
#if _MSC_VER >= 1900
  //expected-error@-2 {{'static' can only be specified inside the class definition}}
#else
  //expected-warning@-4 {{'static' can only be specified inside the class definition}}
#endif
Manna updated this revision to Diff 198514.May 7 2019, 1:09 PM
Manna marked 2 inline comments as done.

Thanks for reviewing. I have updated the test the way it was written before.

Manna added a comment.May 7 2019, 1:21 PM

Thank you for updating the test! One minor nit with the way the test case is written, but otherwise LGTM.

Thanks Aaron. I don't think I have commit right. Could you please submit the patches?

Thanks,
Soumi

aaron.ballman closed this revision.May 8 2019, 6:22 AM

Thank you for updating the test! One minor nit with the way the test case is written, but otherwise LGTM.

Thanks Aaron. I don't think I have commit right. Could you please submit the patches?

Happy to do so -- I've commit in r360250. Thank you for the patch!

Manna added a comment.May 8 2019, 7:16 AM

Thank you for updating the test! One minor nit with the way the test case is written, but otherwise LGTM.

Thanks Aaron. I don't think I have commit right. Could you please submit the patches?

Happy to do so -- I've commit in r360250. Thank you for the patch!

Thank you so much!