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