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; +def warn_conditional_mixed_enum_types : Warning< + "enumeration type mismatch in conditional expression" + "%diff{ ($ and $)|}0,1">, + InGroup; def warn_comparison_of_mixed_enum_types_switch : Warning< "comparison of two values with different enumeration types in switch statement" "%diff{ ($ and $)|}0,1">, 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(); + if (!LHSEnumType) + return; + const EnumType *RHSEnumType = RHSStrippedType->getAs(); + 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);