r373252 - [Diagnostics] Warn if enumeration type mismatch in conditional expression
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 1 07:23:47 PDT 2019
Can we move this behind a Wenum-compare subgroup, say Wenum-compare-type?
Our codebase is (well, was) Wenum-compare clean, and this new warnings
fires pretty often and from a first quick glance the warning looks pretty
low-signal anyways (*). Maybe the subgroup shouldn't even be on by default
-- do you have any data on true / false positive rate of this?
(But for starters, just having a way to turn this off is enough.)
For example, we have a windows common control that's either a PGRP_DOWN or
a PGRP_UP page control and depending on which you store the control state
in the same int, then stuff like `return extra.inner_spin.spin_up ?
UPS_DISABLED : DNS_DISABLED;`.
On Mon, Sep 30, 2019 at 3:53 PM David Bolvansky via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: xbolva00
> Date: Mon Sep 30 12:55:50 2019
> New Revision: 373252
>
> URL: http://llvm.org/viewvc/llvm-project?rev=373252&view=rev
> Log:
> [Diagnostics] Warn if enumeration type mismatch in conditional expression
>
> Summary:
> - Useful warning
> - GCC compatibility (GCC warns in C++ mode)
>
> Reviewers: rsmith, aaron.ballman
>
> Reviewed By: aaron.ballman
>
> Subscribers: cfe-commits
>
> Tags: #clang
>
> Differential Revision: https://reviews.llvm.org/D67919
>
> Added:
> cfe/trunk/test/Sema/warn-conditional-emum-types-mismatch.c
> Modified:
> cfe/trunk/lib/Sema/SemaChecking.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=373252&r1=373251&r2=373252&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Sep 30 12:55:50 2019
> @@ -11308,6 +11308,32 @@ static const IntegerLiteral *getIntegerL
> return IL;
> }
>
> +static void CheckConditionalWithEnumTypes(Sema &S, SourceLocation Loc,
> + Expr *LHS, Expr *RHS) {
> + QualType LHSStrippedType = LHS->IgnoreParenImpCasts()->getType();
> + QualType RHSStrippedType = RHS->IgnoreParenImpCasts()->getType();
> +
> + const auto *LHSEnumType = LHSStrippedType->getAs<EnumType>();
> + if (!LHSEnumType)
> + return;
> + const auto *RHSEnumType = RHSStrippedType->getAs<EnumType>();
> + if (!RHSEnumType)
> + return;
> +
> + // Ignore anonymous enums.
> + if (!LHSEnumType->getDecl()->hasNameForLinkage())
> + return;
> + if (!RHSEnumType->getDecl()->hasNameForLinkage())
> + return;
> +
> + if (S.Context.hasSameUnqualifiedType(LHSStrippedType, RHSStrippedType))
> + return;
> +
> + S.Diag(Loc, diag::warn_conditional_mixed_enum_types)
> + << LHSStrippedType << RHSStrippedType << LHS->getSourceRange()
> + << RHS->getSourceRange();
> +}
> +
> static void DiagnoseIntInBoolContext(Sema &S, Expr *E) {
> E = E->IgnoreParenImpCasts();
> SourceLocation ExprLoc = E->getExprLoc();
> @@ -11799,6 +11825,8 @@ static void CheckConditionalOperator(Sem
> bool Suspicious = false;
> CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious);
> CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious);
> + CheckConditionalWithEnumTypes(S, E->getBeginLoc(), E->getTrueExpr(),
> + E->getFalseExpr());
>
> if (T->isBooleanType())
> DiagnoseIntInBoolContext(S, E);
>
> Added: cfe/trunk/test/Sema/warn-conditional-emum-types-mismatch.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-conditional-emum-types-mismatch.c?rev=373252&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/Sema/warn-conditional-emum-types-mismatch.c (added)
> +++ cfe/trunk/test/Sema/warn-conditional-emum-types-mismatch.c Mon Sep 30
> 12:55:50 2019
> @@ -0,0 +1,39 @@
> +// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wenum-compare %s
> +// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
> +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify -Wenum-compare %s
> +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s
> +
> +enum ro { A = 0x10 };
> +enum rw { B = 0xFF };
> +enum { C = 0x1A};
> +
> +enum {
> + STATUS_SUCCESS,
> + STATUS_FAILURE,
> + MAX_BASE_STATUS_CODE
> +};
> +
> +enum ExtendedStatusCodes {
> + STATUS_SOMETHING_INTERESTING = MAX_BASE_STATUS_CODE + 1000,
> +};
> +
> +
> +int get_flag(int cond) {
> + return cond ? A : B;
> + #ifdef __cplusplus
> + // expected-warning at -2 {{enumeration type mismatch in conditional
> expression ('ro' and 'rw')}}
> + #else
> + // expected-no-diagnostics
> + #endif
> +}
> +
> +// In the following cases we purposefully differ from GCC and dont warn
> because
> +// this code pattern is quite sensitive and we dont want to produce so
> many false positives.
> +
> +int get_flag_anon_enum(int cond) {
> + return cond ? A : C;
> +}
> +
> +int foo(int c) {
> + return c ? STATUS_SOMETHING_INTERESTING : STATUS_SUCCESS;
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191001/345af0bb/attachment.html>
More information about the cfe-commits
mailing list