[PATCH] D67919: [Diagnostics] Warn if enumeration type mismatch in conditional expression
Dávid Bolvanský via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 23 08:31:00 PDT 2019
xbolva00 updated this revision to Diff 221346.
xbolva00 added a comment.
Added test file.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D67919/new/
https://reviews.llvm.org/D67919
Files:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaChecking.cpp
test/Sema/warn-conditional-emum-types-mismatch.c
Index: test/Sema/warn-conditional-emum-types-mismatch.c
===================================================================
--- test/Sema/warn-conditional-emum-types-mismatch.c
+++ test/Sema/warn-conditional-emum-types-mismatch.c
@@ -0,0 +1,21 @@
+// 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};
+
+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
+}
+
+int get_flag_anon_enum(int cond) {
+ return cond ? A : C;
+}
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -11256,6 +11256,34 @@
return true;
}
+static void checkConditionalWithEnumTypes(Sema &S, SourceLocation Loc,
+ Expr *LHS, Expr *RHS) {
+ QualType LHSStrippedType = LHS->IgnoreParenImpCasts()->getType();
+ QualType RHSStrippedType = RHS->IgnoreParenImpCasts()->getType();
+
+ const EnumType *LHSEnumType = LHSStrippedType->getAs<EnumType>();
+ if (!LHSEnumType)
+ return;
+ const EnumType *RHSEnumType = RHSStrippedType->getAs<EnumType>();
+ if (!RHSEnumType)
+ return;
+
+ // Ignore anonymous enums.
+ if (!LHSEnumType->getDecl()->getIdentifier() &&
+ !LHSEnumType->getDecl()->getTypedefNameForAnonDecl())
+ return;
+ if (!RHSEnumType->getDecl()->getIdentifier() &&
+ !RHSEnumType->getDecl()->getTypedefNameForAnonDecl())
+ 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();
@@ -11754,6 +11782,8 @@
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);
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -6156,6 +6156,10 @@
"comparison of two values with different enumeration types"
"%diff{ ($ and $)|}0,1">,
InGroup<EnumCompare>;
+def warn_conditional_mixed_enum_types : Warning<
+ "enumeration type mismatch in conditional expression"
+ "%diff{ ($ and $)|}0,1">,
+ InGroup<EnumCompare>;
def warn_comparison_of_mixed_enum_types_switch : Warning<
"comparison of two values with different enumeration types in switch statement"
"%diff{ ($ and $)|}0,1">,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67919.221346.patch
Type: text/x-patch
Size: 3271 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190923/e714b3d5/attachment.bin>
More information about the cfe-commits
mailing list