-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Clang][Sema]: Allow copy constructor side effects #81127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clang][Sema]: Allow copy constructor side effects #81127
Conversation
@llvm/pr-subscribers-clang Author: Vinayak Dev (vinayakdsci) ChangesFixes #79518 Copy constructors can have initialization with side effects, and thus clang should not emit a warning when -Wunused-variable is used in this context. Currently however, a warning is emitted. Now, compilation happens without warnings. Full diff: https://github.com/llvm/llvm-project/pull/81127.diff 2 Files Affected:
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 18a5d93ab8e8c..7f78aef33f1e3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2044,7 +2044,7 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts,
return false;
if (Init) {
- const auto *Construct = dyn_cast<CXXConstructExpr>(Init);
+ const auto *Construct = dyn_cast<CXXConstructExpr>(Init->IgnoreImpCasts());
if (Construct && !Construct->isElidable()) {
const CXXConstructorDecl *CD = Construct->getConstructor();
if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>() &&
diff --git a/clang/test/SemaCXX/warn-unused-variables.cpp b/clang/test/SemaCXX/warn-unused-variables.cpp
index b649c7d808935..92032a9c2b812 100644
--- a/clang/test/SemaCXX/warn-unused-variables.cpp
+++ b/clang/test/SemaCXX/warn-unused-variables.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify -std=gnu++11 %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify -std=gnu++17 %s
template<typename T> void f() {
T t;
t = 17;
@@ -183,7 +183,7 @@ void foo(int size) {
NonTriviallyDestructible array[2]; // no warning
NonTriviallyDestructible nestedArray[2][2]; // no warning
- Foo fooScalar = 1; // expected-warning {{unused variable 'fooScalar'}}
+ Foo fooScalar = 1; // no warning
Foo fooArray[] = {1,2}; // expected-warning {{unused variable 'fooArray'}}
Foo fooNested[2][2] = { {1,2}, {3,4} }; // expected-warning {{unused variable 'fooNested'}}
}
@@ -297,3 +297,27 @@ void RAIIWrapperTest() {
}
} // namespace gh54489
+
+// Ensure that -Wunused-variable does not emit warning
+// on copy constructors with side effects
+namespace gh79518 {
+
+struct S {
+ S(int);
+};
+
+// With an initializer list
+struct A {
+ int x;
+ A(int x) : x(x) {}
+};
+
+void foo() {
+ S s(0); // no warning
+ S s2 = 0; // no warning
+ S s3{0}; // no warning
+
+ A a = 1; // no warning
+}
+
+} // namespace gh79518
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
3d06ced
to
be1f352
Compare
This change needs a release note. |
be1f352
to
2ecea54
Compare
Done! |
2ecea54
to
f2f9ba7
Compare
@Endilll as you mention on the discourse, I have divided the tests as per the difference in the standards. The tests seem to be working fine. I hope you can review once you find time. Thanks! |
Foo fooScalar = 1; // expected-warning {{unused variable 'fooScalar'}} | ||
#else | ||
Foo fooScalar = 1; // no warning |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code around here can be replaced with a single line:
Foo fooScalar = 1; // cxx98-14-warning {{unused variable 'fooScalar'}}
Look at DR tests again how to make this happen (via -verify=
):
llvm-project/clang/test/CXX/drs/dr0xx.cpp
Lines 1 to 3 in 3902f9b
// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98,cxx98-14 -fexceptions -fcxx-exceptions -pedantic-errors -Wno-bind-to-temporary-copy | |
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11,cxx98-14,cxx11-14 -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple | |
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11,cxx98-14,cxx11-14 -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is documentation for -verify
if you feel you need it: https://clang.llvm.org/docs/InternalsManual.html#verifying-diagnostics
f2f9ba7
to
335d227
Compare
I hope this does it! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Make sure @cor3ntin is happy, too.
@cor3ntin is this good to go? Thanks! |
We have a policy against more than one ping per week, thanks. FYI, if we are not going to fix the C++11 case, we should be very explicit about it. IE this PR is not a complete fix of #79518 |
Sorry about the pings, I think I got a little ahead of myself there. Thanks |
@cor3ntin gentle ping. Could you direct on what other changes are required? Thanks! |
@AaronBallman does not handling c++11 make sense to you? Thanks! |
OK, it looks like there should not be a warning in C++11 and 14 too, as copy initialization with side effects appears to be permitted sine C++11. Thanks! |
@cor3ntin gentle ping. How exactly should I proceed? copy elision was made mandatory in C++17, so wouldn't a warning for C++ < 17 be allowable? I am very happy to implement any suggestions you have for this PR, but I am unable to get the code to work for C++ < 17 because the constructors are not marked elidable in the code for these standards. Specifically in the case where the class object is initialized by an '=' sign instead of an explicit argument being passed. As the RHS of the '=' is different from a Also, this would involve a conversion process in the code? I would really appreciate pointers on how to solve this problem, and how to improve this PR too. Thanks! |
@AaronBallman does this PR look good to go, or should I make any changes and updates? I would really be grateful for any pointers on how this can be improved. Thanks a lot! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should handle pre-C++17 as well, because the constructors are called there: https://godbolt.org/z/YWjb8P67c (the ASTs are different but the runtime effects are not).
clang/docs/ReleaseNotes.rst
Outdated
- Clang now doesn't produce false-positive warning `-Wunused-variable` | ||
for variables created through copy initialization having side-effects in C++17 and later. | ||
Fixes (`#79518 <https://github.com/llvm/llvm-project/issues/79518>`_). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Clang now doesn't produce false-positive warning `-Wunused-variable` | |
for variables created through copy initialization having side-effects in C++17 and later. | |
Fixes (`#79518 <https://github.com/llvm/llvm-project/issues/79518>`_). | |
- Clang no longer produces a false-positive `-Wunused-variable` warning | |
for variables created through copy initialization having side-effects in C++17 and later. | |
Fixes (`#79518 <https://github.com/llvm/llvm-project/issues/79518>`_). |
@AaronBallman C++17 and later mark all of these constructor calls as non-elidable after ignoring the implicit casts, while C++14 and before mark the constructor that is assigned by |
I just looked into the code and now I think it is reasonable to leave the C++14 and earlier behavior alone on the assumption that it's good enough for now and because the C++17 and up changes are an improvement. Whether a constructor is or isn't elidable is complex and there's a fair number of FIXME comments around it, so I don't think we should tie that to this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from some grammatical changes to the release note, the changes LGTM! Do you need someone to land this on your behalf once those changes are made?
335d227
to
d4df9a7
Compare
Thank you so much! I have made changes to the Release Notes as you suggested. Thanks for your review!
Yes, I don't have commit access at present, so I would really appreciate it if you or someone else could land it on my behalf. Again, a big thanks! |
Fixes #79518
Copy constructors can have initialization with side effects, and thus clang should not emit a warning when -Wunused-variable is used in this context. Currently however, a warning is emitted.
Now, compilation happens without warnings.