This is an archive of the discontinued LLVM Phabricator instance.

Corrrect warn_unused_result attribute
ClosedPublic

Authored by erichkeane on Apr 18 2017, 5:43 PM.

Details

Summary

The original idea was that if the attribute on an operator, that the return-value unused-ness wouldn't matter. However, all of the operators except postfix inc/dec return references! References don't result in this warning anyway, so those are already excluded.

However, the existing patch(in addition to missing a bunch of valid cases, such as a function returning a copy) would still hit non-member operators anyway! This patch removes the previous condition (if our current function is in the warn-unused-result'ed type) and replaces it with one that explicitly checks for post inc/dec (since these are likely going to be SO common that warning on them would be extreme).

Diff Detail

Repository
rL LLVM

Event Timeline

erichkeane created this revision.Apr 18 2017, 5:43 PM
aaron.ballman added inline comments.Apr 19 2017, 6:37 AM
lib/AST/Decl.cpp
3007 ↗(On Diff #95664)

Please don't use auto here.

3010 ↗(On Diff #95664)

CXXMethodDecl represents a static or instance method, so I'm not certain this logic is quite correct.

test/SemaCXX/warn-unused-result.cpp
166 ↗(On Diff #95664)

Can you also add a test with [[nodiscard]] and verify that the uses of increment/decrement *are* diagnosed?

erichkeane marked an inline comment as done.Apr 19 2017, 9:48 AM
erichkeane added inline comments.
lib/AST/Decl.cpp
3010 ↗(On Diff #95664)

I actually stole this logic from lib/Sema/SemaDeclCXX.cpp lines 12708 and 12754. I believe the logic here is that it operators aren't allowed to be static? Since it is illegal to do so, I would expect that I'd simply need to do an assert to prevent it?

I'm open for ideas if you have one here, I'm not sure what the 'right' thing to do is.

test/SemaCXX/warn-unused-result.cpp
166 ↗(On Diff #95664)

I can add that, it will obviously cause a slight change in logic since I didn't handle that separately. Are we surewe WANT [[nodiscard]] to warn in this case?

1 more thing: I excepted post-increment/decrement from this warning because I figured it would give a TON of warnings from people using post-inc/dec in for loops.

However, after further discussion with Craig (who brought this up on the mailing list), I severely wonder if that is the 'right' thing to do. Someone who is going to mark their struct in this way would likely ALSO mean it in this case, right?

Aaron: Should I simply remove the special casing all together, so that it warns on post inc/dec? That would definitely solve all your concerns in the review so far.

1 more thing: I excepted post-increment/decrement from this warning because I figured it would give a TON of warnings from people using post-inc/dec in for loops.

However, after further discussion with Craig (who brought this up on the mailing list), I severely wonder if that is the 'right' thing to do. Someone who is going to mark their struct in this way would likely ALSO mean it in this case, right?

Aaron: Should I simply remove the special casing all together, so that it warns on post inc/dec? That would definitely solve all your concerns in the review so far.

I think that would make sense, yes.

lib/AST/Decl.cpp
3010 ↗(On Diff #95664)

I was wondering more how a friend declaration of the operator might show up. e.g.,

struct S {
  friend S operator++(S Operand, int);
};
test/SemaCXX/warn-unused-result.cpp
166 ↗(On Diff #95664)

I think so, yes. The C++ standard doesn't provide normative requirements here, but its encouragement to implementers doesn't mention this kind of behavior. [dcl.attr.nodiscard]p2:

A nodiscard call is a function call expression that calls a function previously declared nodiscard, or
whose return type is a possibly cv-qualified class or enumeration type marked nodiscard. Appearance of a nodiscard call as a potentially-evaluated discarded-value expression (Clause 8) is discouraged unless explicitly cast to void. Implementations are encouraged to issue a warning in such cases. This is typically because discarding the return value of a nodiscard call has surprising consequences.

Since this is returning a class type that is marked as nodiscard, I would expect it to be diagnosed with the standard attribute spelling.

As discussed, removed the exception for postfix operators. It seems like the right thing to do.I didn't add the [[nodiscard]] test, since it is the same intended behavior now.

I'm surprised this change didn't cause any other tests to need to be updated. A few small formatting nits and a request for another test, but otherwise looking good.

test/SemaCXX/warn-unused-result.cpp
166 ↗(On Diff #95797)

Add a space between struct and the attribute introducer.

175 ↗(On Diff #95797)

Same here.

200 ↗(On Diff #95797)

Can you add some tests showing that casting to void still silence the diagnostic even for these operator cases? It doesn't need to happen for all of them, but it's good to ensure that still behaves as expected.

erichkeane updated this revision to Diff 95807.Apr 19 2017, 1:20 PM
erichkeane marked 3 inline comments as done.

Added the tests, plus the two formatting changes.

This revision is now accepted and ready to land.Apr 19 2017, 1:23 PM
This revision was automatically updated to reflect the committed changes.