r224465 - Adding a -Wunused-value warning for expressions with side effects used in an unevaluated expression context, such as sizeof(), or decltype(). Also adds a similar warning when the expression passed to typeid() *is* evaluated, since it is equally likely that the user would expect the expression operand to be unevaluated in that case.
Stephan Bergmann
sbergman at redhat.com
Fri Dec 19 06:03:15 PST 2014
On 12/19/2014 02:20 PM, Timur Iskhodzhanov wrote:
> I believe this is a false positive:
> -----------------------------------------
> #include <typeinfo>
> #include <vector>
>
> struct A {
> virtual ~A();
> };
>
> const char *foo(const std::vector<A*> &v) {
> const std::type_info &t = typeid(*v[0]);
> return t.name <http://t.name>();
> }
> -----------------------------------------
>
> This warning seems to be pretty annoying as it's on by default.
>
> Is it possible to revert/disable and reland it gradually, making sure we
> don't get false positives along the way?
> or at least put it under a separate flag for the time being?
Yes, this annoyed me too when building LibreOffice, quite a number of
places there that use typeid(*...) dereferencing complex expressions
yielding polymorphic pointers, so I hacked my local Clang for now with
> Index: lib/Sema/SemaExprCXX.cpp
> ===================================================================
> --- lib/Sema/SemaExprCXX.cpp (revision 224504)
> +++ lib/Sema/SemaExprCXX.cpp (working copy)
> @@ -449,10 +449,18 @@
> else if (ActiveTemplateInstantiations.empty() &&
> E->HasSideEffects(Context, WasEvaluated)) {
> // The expression operand for typeid is in an unevaluated expression
> - // context, so side effects could result in unintended consequences.
> - Diag(E->getExprLoc(), WasEvaluated
> - ? diag::warn_side_effects_typeid
> - : diag::warn_side_effects_unevaluated_context);
> + // context, so side effects could result in unintended consequences (but
> + // suppress warnings when dereferencing a pointer [TODO: to non-final class
> + // type], so evaluation of the expression, including side effects and all,
> + // is likely expected after all).
> + UnaryOperator *Op;
> + if (!WasEvaluated ||
> + ((Op = dyn_cast<UnaryOperator>(E->IgnoreParenImpCasts())) &&
> + Op->getOpcode() == UO_AddrOf)) {
> + Diag(E->getExprLoc(), WasEvaluated
> + ? diag::warn_side_effects_typeid
> + : diag::warn_side_effects_unevaluated_context);
> + }
> }
>
> return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
Stephan
More information about the cfe-commits
mailing list