[clang] 4b00299 - [c++20] Add deprecation warnings for the expression forms deprecated by P1120R0.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 16 17:49:55 PST 2019
Author: Richard Smith
Date: 2019-12-16T17:49:45-08:00
New Revision: 4b0029995853fe37d1dc95ef96f46697c743fcad
URL: https://github.com/llvm/llvm-project/commit/4b0029995853fe37d1dc95ef96f46697c743fcad
DIFF: https://github.com/llvm/llvm-project/commit/4b0029995853fe37d1dc95ef96f46697c743fcad.diff
LOG: [c++20] Add deprecation warnings for the expression forms deprecated by P1120R0.
This covers:
* usual arithmetic conversions (comparisons, arithmetic, conditionals)
between different enumeration types
* usual arithmetic conversions between enums and floating-point types
* comparisons between two operands of array type
The deprecation warnings are on-by-default (in C++20 compilations); it
seems likely that these forms will become ill-formed in C++23, so
warning on them now by default seems wise.
For the first two bullets, off-by-default warnings were also added for
all the cases where we didn't already have warnings (covering language
modes prior to C++20). These warnings are in subgroups of the existing
-Wenum-conversion (except that the first case is not warned on if either
enumeration type is anonymous, consistent with our existing
-Wenum-conversion warnings).
Added:
clang/test/CXX/expr/expr.arith.conv/p2.cpp
Modified:
clang/include/clang/AST/Type.h
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/AST/Type.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/test/Sema/switch.c
clang/test/Sema/warn-conditional-emum-types-mismatch.c
clang/test/SemaCXX/deprecated.cpp
clang/test/SemaCXX/self-comparison.cpp
clang/test/SemaCXX/warn-enum-compare.cpp
clang/www/cxx_status.html
Removed:
################################################################################
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 882b5947c9f4..25ab44c4bcbe 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1973,6 +1973,7 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
/// Determine whether this type is an integral or unscoped enumeration type.
bool isIntegralOrUnscopedEnumerationType() const;
+ bool isUnscopedEnumerationType() const;
/// Floating point categories.
bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 6cb1a4e0700d..8aa93d4138a2 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -60,7 +60,27 @@ def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
UndefinedBoolConversion]>;
def IntConversion : DiagGroup<"int-conversion">;
-def EnumConversion : DiagGroup<"enum-conversion">;
+def DeprecatedEnumCompareConditional :
+ DiagGroup<"deprecated-enum-compare-conditional">;
+def EnumCompareConditional : DiagGroup<"enum-compare-conditional",
+ [DeprecatedEnumCompareConditional]>;
+def EnumCompareSwitch : DiagGroup<"enum-compare-switch">;
+def DeprecatedEnumCompare : DiagGroup<"deprecated-enum-compare">;
+def EnumCompare : DiagGroup<"enum-compare", [EnumCompareSwitch,
+ DeprecatedEnumCompare]>;
+def DeprecatedAnonEnumEnumConversion : DiagGroup<"deprecated-anon-enum-enum-conversion">;
+def DeprecatedEnumEnumConversion : DiagGroup<"deprecated-enum-enum-conversion">;
+def DeprecatedEnumFloatConversion : DiagGroup<"deprecated-enum-float-conversion">;
+def AnonEnumEnumConversion : DiagGroup<"anon-enum-enum-conversion",
+ [DeprecatedAnonEnumEnumConversion]>;
+def EnumEnumConversion : DiagGroup<"enum-enum-conversion",
+ [DeprecatedEnumEnumConversion]>;
+def EnumFloatConversion : DiagGroup<"enum-float-conversion",
+ [DeprecatedEnumFloatConversion]>;
+def EnumConversion : DiagGroup<"enum-conversion",
+ [EnumEnumConversion,
+ EnumFloatConversion,
+ EnumCompareConditional]>;
def ObjCSignedCharBoolImplicitIntConversion :
DiagGroup<"objc-signed-char-bool-implicit-int-conversion">;
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion",
@@ -126,6 +146,7 @@ def FinalDtorNonFinalClass : DiagGroup<"final-dtor-non-final-class">;
def CXX11CompatDeprecatedWritableStr :
DiagGroup<"c++11-compat-deprecated-writable-strings">;
+def DeprecatedArrayCompare : DiagGroup<"deprecated-array-compare">;
def DeprecatedAttributes : DiagGroup<"deprecated-attributes">;
def DeprecatedCommaSubscript : DiagGroup<"deprecated-comma-subscript">;
def DeprecatedCopy : DiagGroup<"deprecated-copy">;
@@ -147,12 +168,18 @@ def DeprecatedVolatile : DiagGroup<"deprecated-volatile">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>;
// FIXME: Why is DeprecatedImplementations not in this group?
-def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
+def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
+ DeprecatedArrayCompare,
+ DeprecatedAttributes,
DeprecatedCommaSubscript,
DeprecatedCopy,
DeprecatedCopyDtor,
DeprecatedDeclarations,
DeprecatedDynamicExceptionSpec,
+ DeprecatedEnumCompare,
+ DeprecatedEnumCompareConditional,
+ DeprecatedEnumEnumConversion,
+ DeprecatedEnumFloatConversion,
DeprecatedIncrementBool,
DeprecatedRegister,
DeprecatedThisCapture,
@@ -573,9 +600,6 @@ def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
def SwitchBool : DiagGroup<"switch-bool">;
def SwitchEnum : DiagGroup<"switch-enum">;
def Switch : DiagGroup<"switch">;
-def EnumCompareConditional : DiagGroup<"enum-compare-conditional">;
-def EnumCompareSwitch : DiagGroup<"enum-compare-switch">;
-def EnumCompare : DiagGroup<"enum-compare", [EnumCompareSwitch]>;
def ImplicitFallthroughPerFunction :
DiagGroup<"implicit-fallthrough-per-function">;
def ImplicitFallthrough : DiagGroup<"implicit-fallthrough",
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d657c29adafd..8f303f2f1496 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6219,6 +6219,52 @@ def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error<
"%
diff { ($ and $)|}0,1}2"
" which are pointers to non-overlapping address spaces">;
+def select_arith_conv_kind : TextSubstitution<
+ "%select{arithmetic between|bitwise operation between|comparison of|"
+ "conditional expression between|compound assignment of}0">;
+def warn_arith_conv_enum_float : Warning<
+ "%sub{select_arith_conv_kind}0 "
+ "%select{floating-point|enumeration}1 type %2 "
+ "%plural{2:with|4:from|:and}0 "
+ "%select{enumeration|floating-point}1 type %3">,
+ InGroup<EnumFloatConversion>, DefaultIgnore;
+def warn_arith_conv_enum_float_cxx2a : Warning<
+ "%sub{select_arith_conv_kind}0 "
+ "%select{floating-point|enumeration}1 type %2 "
+ "%plural{2:with|4:from|:and}0 "
+ "%select{enumeration|floating-point}1 type %3 is deprecated">,
+ InGroup<DeprecatedEnumFloatConversion>;
+def warn_arith_conv_mixed_enum_types : Warning<
+ "%sub{select_arith_conv_kind}0 "
+ "
diff erent enumeration types%
diff { ($ and $)|}1,2">,
+ InGroup<EnumEnumConversion>, DefaultIgnore;
+def warn_arith_conv_mixed_enum_types_cxx2a : Warning<
+ "%sub{select_arith_conv_kind}0 "
+ "
diff erent enumeration types%
diff { ($ and $)|}1,2 is deprecated">,
+ InGroup<DeprecatedEnumEnumConversion>;
+def warn_arith_conv_mixed_anon_enum_types : Warning<
+ warn_arith_conv_mixed_enum_types.Text>,
+ InGroup<AnonEnumEnumConversion>, DefaultIgnore;
+def warn_arith_conv_mixed_anon_enum_types_cxx2a : Warning<
+ warn_arith_conv_mixed_enum_types_cxx2a.Text>,
+ InGroup<DeprecatedAnonEnumEnumConversion>;
+def warn_conditional_mixed_enum_types : Warning<
+ warn_arith_conv_mixed_enum_types.Text>,
+ InGroup<EnumCompareConditional>, DefaultIgnore;
+def warn_conditional_mixed_enum_types_cxx2a : Warning<
+ warn_arith_conv_mixed_enum_types_cxx2a.Text>,
+ InGroup<DeprecatedEnumCompareConditional>;
+def warn_comparison_mixed_enum_types : Warning<
+ warn_arith_conv_mixed_enum_types.Text>,
+ InGroup<EnumCompare>;
+def warn_comparison_mixed_enum_types_cxx2a : Warning<
+ warn_arith_conv_mixed_enum_types_cxx2a.Text>,
+ InGroup<DeprecatedEnumCompare>;
+def warn_comparison_of_mixed_enum_types_switch : Warning<
+ "comparison of
diff erent enumeration types in switch statement"
+ "%
diff { ($ and $)|}0,1">,
+ InGroup<EnumCompareSwitch>;
+
def err_typecheck_assign_const : Error<
"%select{"
"cannot assign to return value because function %1 returns a const value|"
@@ -6272,18 +6318,6 @@ def warn_left_shift_always : Warning<
"converting the result of '<<' to a boolean always evaluates "
"to %select{false|true}0">,
InGroup<TautologicalConstantCompare>;
-def warn_comparison_of_mixed_enum_types : Warning<
- "comparison of two values with
diff erent 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<EnumCompareConditional>, DefaultIgnore;
-def warn_comparison_of_mixed_enum_types_switch : Warning<
- "comparison of two values with
diff erent enumeration types in switch statement"
- "%
diff { ($ and $)|}0,1">,
- InGroup<EnumCompareSwitch>;
def warn_null_in_arithmetic_operation : Warning<
"use of NULL in arithmetic operation">,
InGroup<NullArithmetic>;
@@ -8507,6 +8541,10 @@ def warn_comparison_bitwise_or : Warning<
def warn_tautological_overlap_comparison : Warning<
"overlapping comparisons always evaluate to %select{false|true}0">,
InGroup<TautologicalOverlapCompare>, DefaultIgnore;
+def warn_depr_array_comparison : Warning<
+ "comparison between two arrays is deprecated; "
+ "to compare array addresses, use unary '+' to decay operands to pointers">,
+ InGroup<DeprecatedArrayCompare>;
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a4a4c2ab2ed5..238cd913530a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10344,13 +10344,27 @@ class Sema final {
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
FunctionDecl *FDecl);
+ /// Context in which we're performing a usual arithmetic conversion.
+ enum ArithConvKind {
+ /// An arithmetic operation.
+ ACK_Arithmetic,
+ /// A bitwise operation.
+ ACK_BitwiseOp,
+ /// A comparison.
+ ACK_Comparison,
+ /// A conditional (?:) operator.
+ ACK_Conditional,
+ /// A compound assignment expression.
+ ACK_CompAssign,
+ };
+
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
// operands and then handles various conversions that are common to binary
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this
// routine returns the first non-arithmetic type found. The client is
// responsible for emitting appropriate error diagnostics.
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
- bool IsCompAssign = false);
+ SourceLocation Loc, ArithConvKind ACK);
/// AssignConvertType - All of the 'assignment' semantic checks return this
/// enum to indicate whether the assignment was allowed. These checks are
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 2eae2ebb6174..85447d682ba2 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -1856,7 +1856,10 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Int128;
+ return isUnscopedEnumerationType();
+}
+bool Type::isUnscopedEnumerationType() const {
// Check for a complete enum type; incomplete enum types are not properly an
// enumeration type in the sense required here.
// C++0x: However, if the underlying type of the enum is fixed, it is
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index aff63aef2934..910afefffb6d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5756,7 +5756,8 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
// Do standard promotions between the two arguments, returning their common
// type.
- QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
+ QualType Res = UsualArithmeticConversions(
+ OrigArg0, OrigArg1, TheCall->getExprLoc(), ACK_Comparison);
if (OrigArg0.isInvalid() || OrigArg1.isInvalid())
return true;
@@ -11514,32 +11515,6 @@ static const IntegerLiteral *getIntegerLiteral(Expr *E) {
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();
@@ -12031,8 +12006,6 @@ static void CheckConditionalOperator(Sema &S, ConditionalOperator *E,
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);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e1921f0ddf78..86c3684d03f4 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1333,13 +1333,72 @@ static QualType handleFixedPointConversion(Sema &S, QualType LHSTy,
return ResultTy;
}
+/// Check that the usual arithmetic conversions can be performed on this pair of
+/// expressions that might be of enumeration type.
+static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS,
+ SourceLocation Loc,
+ Sema::ArithConvKind ACK) {
+ // C++2a [expr.arith.conv]p1:
+ // If one operand is of enumeration type and the other operand is of a
+ //
diff erent enumeration type or a floating-point type, this behavior is
+ // deprecated ([depr.arith.conv.enum]).
+ //
+ // Warn on this in all language modes. Produce a deprecation warning in C++20.
+ // Eventually we will presumably reject these cases (in C++23 onwards?).
+ QualType L = LHS->getType(), R = RHS->getType();
+ bool LEnum = L->isUnscopedEnumerationType(),
+ REnum = R->isUnscopedEnumerationType();
+ bool IsCompAssign = ACK == Sema::ACK_CompAssign;
+ if ((!IsCompAssign && LEnum && R->isFloatingType()) ||
+ (REnum && L->isFloatingType())) {
+ S.Diag(Loc, S.getLangOpts().CPlusPlus2a
+ ? diag::warn_arith_conv_enum_float_cxx2a
+ : diag::warn_arith_conv_enum_float)
+ << LHS->getSourceRange() << RHS->getSourceRange()
+ << (int)ACK << LEnum << L << R;
+ } else if (!IsCompAssign && LEnum && REnum &&
+ !S.Context.hasSameUnqualifiedType(L, R)) {
+ unsigned DiagID;
+ if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() ||
+ !R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) {
+ // If either enumeration type is unnamed, it's less likely that the
+ // user cares about this, but this situation is still deprecated in
+ // C++2a. Use a
diff erent warning group.
+ DiagID = S.getLangOpts().CPlusPlus2a
+ ? diag::warn_arith_conv_mixed_anon_enum_types_cxx2a
+ : diag::warn_arith_conv_mixed_anon_enum_types;
+ } else if (ACK == Sema::ACK_Conditional) {
+ // Conditional expressions are separated out because they have
+ // historically had a
diff erent warning flag.
+ DiagID = S.getLangOpts().CPlusPlus2a
+ ? diag::warn_conditional_mixed_enum_types_cxx2a
+ : diag::warn_conditional_mixed_enum_types;
+ } else if (ACK == Sema::ACK_Comparison) {
+ // Comparison expressions are separated out because they have
+ // historically had a
diff erent warning flag.
+ DiagID = S.getLangOpts().CPlusPlus2a
+ ? diag::warn_comparison_mixed_enum_types_cxx2a
+ : diag::warn_comparison_mixed_enum_types;
+ } else {
+ DiagID = S.getLangOpts().CPlusPlus2a
+ ? diag::warn_arith_conv_mixed_enum_types_cxx2a
+ : diag::warn_arith_conv_mixed_enum_types;
+ }
+ S.Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange()
+ << (int)ACK << L << R;
+ }
+}
+
/// UsualArithmeticConversions - Performs various conversions that are common to
/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
/// routine returns the first non-arithmetic type found. The client is
/// responsible for emitting appropriate error diagnostics.
QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
- bool IsCompAssign) {
- if (!IsCompAssign) {
+ SourceLocation Loc,
+ ArithConvKind ACK) {
+ checkEnumArithmeticConversions(*this, LHS.get(), RHS.get(), Loc, ACK);
+
+ if (ACK != ACK_CompAssign) {
LHS = UsualUnaryConversions(LHS.get());
if (LHS.isInvalid())
return QualType();
@@ -1376,7 +1435,7 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(LHS.get());
if (!LHSBitfieldPromoteTy.isNull())
LHSType = LHSBitfieldPromoteTy;
- if (LHSType != LHSUnpromotedType && !IsCompAssign)
+ if (LHSType != LHSUnpromotedType && ACK != ACK_CompAssign)
LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast);
// If both types are identical, no conversion is needed.
@@ -1393,24 +1452,24 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
// Handle complex types first (C99 6.3.1.8p1).
if (LHSType->isComplexType() || RHSType->isComplexType())
return handleComplexFloatConversion(*this, LHS, RHS, LHSType, RHSType,
- IsCompAssign);
+ ACK == ACK_CompAssign);
// Now handle "real" floating types (i.e. float, double, long double).
if (LHSType->isRealFloatingType() || RHSType->isRealFloatingType())
return handleFloatConversion(*this, LHS, RHS, LHSType, RHSType,
- IsCompAssign);
+ ACK == ACK_CompAssign);
// Handle GCC complex int extension.
if (LHSType->isComplexIntegerType() || RHSType->isComplexIntegerType())
return handleComplexIntConversion(*this, LHS, RHS, LHSType, RHSType,
- IsCompAssign);
+ ACK == ACK_CompAssign);
if (LHSType->isFixedPointType() || RHSType->isFixedPointType())
return handleFixedPointConversion(*this, LHSType, RHSType);
// Finally, we have two
diff ering integer types.
return handleIntegerConversion<doIntegralCast, doIntegralCast>
- (*this, LHS, RHS, LHSType, RHSType, IsCompAssign);
+ (*this, LHS, RHS, LHSType, RHSType, ACK == ACK_CompAssign);
}
//===----------------------------------------------------------------------===//
@@ -7393,7 +7452,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
/*AllowBothBool*/true,
/*AllowBoolConversions*/false);
- QualType ResTy = UsualArithmeticConversions(LHS, RHS);
+ QualType ResTy =
+ UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
@@ -9312,7 +9372,8 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
/*AllowBothBool*/getLangOpts().AltiVec,
/*AllowBoolConversions*/false);
- QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign);
+ QualType compType = UsualArithmeticConversions(
+ LHS, RHS, Loc, IsCompAssign ? ACK_CompAssign : ACK_Arithmetic);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
@@ -9340,7 +9401,8 @@ QualType Sema::CheckRemainderOperands(
return InvalidOperands(Loc, LHS, RHS);
}
- QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign);
+ QualType compType = UsualArithmeticConversions(
+ LHS, RHS, Loc, IsCompAssign ? ACK_CompAssign : ACK_Arithmetic);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
@@ -9629,7 +9691,8 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
return compType;
}
- QualType compType = UsualArithmeticConversions(LHS, RHS, CompLHSTy);
+ QualType compType = UsualArithmeticConversions(
+ LHS, RHS, Loc, CompLHSTy ? ACK_CompAssign : ACK_Arithmetic);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
@@ -9723,7 +9786,8 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
return compType;
}
- QualType compType = UsualArithmeticConversions(LHS, RHS, CompLHSTy);
+ QualType compType = UsualArithmeticConversions(
+ LHS, RHS, Loc, CompLHSTy ? ACK_CompAssign : ACK_Arithmetic);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
@@ -10054,35 +10118,6 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
return LHSType;
}
-/// If two
diff erent enums are compared, raise a warning.
-static void checkEnumComparison(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_comparison_of_mixed_enum_types)
- << LHSStrippedType << RHSStrippedType
- << LHS->getSourceRange() << RHS->getSourceRange();
-}
-
/// Diagnose bad pointer comparisons.
static void diagnoseDistinctPointerComparison(Sema &S, SourceLocation Loc,
ExprResult &LHS, ExprResult &RHS,
@@ -10380,6 +10415,19 @@ static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc,
AlwaysEqual, // std::strong_ordering::equal from operator<=>
};
+ // C++2a [depr.array.comp]:
+ // Equality and relational comparisons ([expr.eq], [expr.rel]) between two
+ // operands of array type are deprecated.
+ if (S.getLangOpts().CPlusPlus2a && LHSStripped->getType()->isArrayType() &&
+ RHSStripped->getType()->isArrayType()) {
+ S.Diag(Loc, diag::warn_depr_array_comparison)
+ << LHS->getSourceRange() << RHS->getSourceRange()
+ << LHSStripped->getType() << RHSStripped->getType();
+ // Carry on to produce the tautological comparison warning, if this
+ // expression is potentially-evaluated, we can resolve the array to a
+ // non-weak declaration, and so on.
+ }
+
if (!LHS->getBeginLoc().isMacroID() && !RHS->getBeginLoc().isMacroID()) {
if (Expr::isSameComparisonOperand(LHS, RHS)) {
unsigned Result;
@@ -10558,6 +10606,7 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
return QualType();
}
+ // FIXME: Consider combining this with checkEnumArithmeticConversions.
int NumEnumArgs = (int)LHSStrippedType->isEnumeralType() +
RHSStrippedType->isEnumeralType();
if (NumEnumArgs == 1) {
@@ -10593,7 +10642,8 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
// C++2a [expr.spaceship]p4: If both operands have arithmetic types, the
// usual arithmetic conversions are applied to the operands.
- QualType Type = S.UsualArithmeticConversions(LHS, RHS);
+ QualType Type =
+ S.UsualArithmeticConversions(LHS, RHS, Loc, Sema::ACK_Comparison);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
if (Type.isNull())
@@ -10624,15 +10674,14 @@ static QualType checkArithmeticOrEnumeralCompare(Sema &S, ExprResult &LHS,
return checkArithmeticOrEnumeralThreeWayCompare(S, LHS, RHS, Loc);
// C99 6.5.8p3 / C99 6.5.9p4
- QualType Type = S.UsualArithmeticConversions(LHS, RHS);
+ QualType Type =
+ S.UsualArithmeticConversions(LHS, RHS, Loc, Sema::ACK_Comparison);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
if (Type.isNull())
return S.InvalidOperands(Loc, LHS, RHS);
assert(Type->isArithmeticType() || Type->isEnumeralType());
- checkEnumComparison(S, Loc, LHS.get(), RHS.get());
-
if (Type->isAnyComplexType() && BinaryOperator::isRelationalOp(Opc))
return S.InvalidOperands(Loc, LHS, RHS);
@@ -11335,9 +11384,13 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
if (Opc == BO_And)
diagnoseLogicalNotOnLHSofCheck(*this, LHS, RHS, Loc, Opc);
+ if (LHS.get()->getType()->hasFloatingRepresentation() ||
+ RHS.get()->getType()->hasFloatingRepresentation())
+ return InvalidOperands(Loc, LHS, RHS);
+
ExprResult LHSResult = LHS, RHSResult = RHS;
- QualType compType = UsualArithmeticConversions(LHSResult, RHSResult,
- IsCompAssign);
+ QualType compType = UsualArithmeticConversions(
+ LHSResult, RHSResult, Loc, IsCompAssign ? ACK_CompAssign : ACK_BitwiseOp);
if (LHSResult.isInvalid() || RHSResult.isInvalid())
return QualType();
LHS = LHSResult.get();
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 9e5e49fa0f93..47b58df0acd9 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5993,7 +5993,8 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// the usual arithmetic conversions are performed to bring them to a
// common type, and the result is of that type.
if (LTy->isArithmeticType() && RTy->isArithmeticType()) {
- QualType ResTy = UsualArithmeticConversions(LHS, RHS);
+ QualType ResTy =
+ UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
if (ResTy.isNull()) {
diff --git a/clang/test/CXX/expr/expr.arith.conv/p2.cpp b/clang/test/CXX/expr/expr.arith.conv/p2.cpp
new file mode 100644
index 000000000000..0df3e302d0b3
--- /dev/null
+++ b/clang/test/CXX/expr/expr.arith.conv/p2.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -verify %s -std=c++17 -Weverything -Wno-deprecated -Wno-float-equal
+// RUN: %clang_cc1 -verify %s -std=c++2a -Wdeprecated
+
+static enum E1 {} e1, e1b;
+static enum E2 {} e2;
+static double d;
+extern void f();
+extern bool b;
+
+void f() {
+ void(e1 * e1);
+ void(e1 * e2); // expected-warning {{arithmetic between
diff erent enumeration types}}
+ void(e1 * d); // expected-warning {{arithmetic between enumeration type 'enum E1' and floating-point type 'double'}}
+ void(d * e1); // expected-warning {{arithmetic between floating-point type 'double' and enumeration type 'enum E1'}}
+
+ void(e1 + e1);
+ void(e1 + e2); // expected-warning {{arithmetic between
diff erent enumeration types}}
+ void(e1 + d); // expected-warning {{arithmetic between enumeration type 'enum E1' and floating-point type 'double'}}
+ void(d + e1); // expected-warning {{arithmetic between floating-point type 'double' and enumeration type 'enum E1'}}
+
+#if __cplusplus > 201703L
+ void(e1 <=> e1b); // expected-error {{include <compare>}}
+ void(e1 <=> e2); // expected-error {{invalid operands}}
+ void(e1 <=> d); // expected-error {{invalid operands}}
+ void(d <=> e1); // expected-error {{invalid operands}}
+#endif
+
+ void(e1 < e1b);
+ void(e1 < e2); // expected-warning {{comparison of
diff erent enumeration types}}
+ void(e1 < d); // expected-warning {{comparison of enumeration type 'enum E1' with floating-point type 'double'}}
+ void(d < e1); // expected-warning {{comparison of floating-point type 'double' with enumeration type 'enum E1'}}
+
+ void(e1 == e1b);
+ void(e1 == e2); // expected-warning {{comparison of
diff erent enumeration types}}
+ void(e1 == d); // expected-warning {{comparison of enumeration type 'enum E1' with floating-point type 'double'}}
+ void(d == e1); // expected-warning {{comparison of floating-point type 'double' with enumeration type 'enum E1'}}
+
+ void(b ? e1 : e1b);
+ void(b ? e1 : e2); // expected-warning {{conditional expression between
diff erent enumeration types}}
+ void(b ? e1 : d); // expected-warning {{conditional expression between enumeration type 'enum E1' and floating-point type 'double'}}
+ void(b ? d : e1); // expected-warning {{conditional expression between floating-point type 'double' and enumeration type 'enum E1'}}
+
+ void(e1 = e1b);
+ void(e1 = e2); // expected-error {{incompatible}}
+ void(e1 = d); // expected-error {{incompatible}}
+ void(d = e1); // FIXME: Should we warn on this?
+
+ void(e1 += e1b); // expected-error {{incompatible}}
+ void(e1 += e2); // expected-error {{incompatible}}
+ void(e1 += d); // expected-error {{incompatible}}
+ void(d += e1); // expected-warning {{compound assignment of floating-point type 'double' from enumeration type 'enum E1'}}
+}
diff --git a/clang/test/Sema/switch.c b/clang/test/Sema/switch.c
index f704c886c96f..2c9fe915d4c4 100644
--- a/clang/test/Sema/switch.c
+++ b/clang/test/Sema/switch.c
@@ -383,7 +383,7 @@ void switch_on_ExtendedEnum1(enum ExtendedEnum1 e) {
case EE1_b: break;
case EE1_c: break; // no-warning
case EE1_d: break; // expected-warning {{case value not in enumerated type 'enum ExtendedEnum1'}}
- // expected-warning at -1 {{comparison of two values with
diff erent enumeration types in switch statement ('enum ExtendedEnum1' and 'enum ExtendedEnum1_unrelated')}}
+ // expected-warning at -1 {{comparison of
diff erent enumeration types in switch statement ('enum ExtendedEnum1' and 'enum ExtendedEnum1_unrelated')}}
}
}
diff --git a/clang/test/Sema/warn-conditional-emum-types-mismatch.c b/clang/test/Sema/warn-conditional-emum-types-mismatch.c
index 12264ff89270..c9e2eddc7764 100644
--- a/clang/test/Sema/warn-conditional-emum-types-mismatch.c
+++ b/clang/test/Sema/warn-conditional-emum-types-mismatch.c
@@ -19,7 +19,7 @@ enum ExtendedStatusCodes {
int get_flag(int cond) {
return cond ? A : B;
#ifdef __cplusplus
- // expected-warning at -2 {{enumeration type mismatch in conditional expression ('ro' and 'rw')}}
+ // expected-warning at -2 {{conditional expression between
diff erent enumeration types ('ro' and 'rw')}}
#else
// expected-no-diagnostics
#endif
diff --git a/clang/test/SemaCXX/deprecated.cpp b/clang/test/SemaCXX/deprecated.cpp
index b303c2b4225c..b2320c41073c 100644
--- a/clang/test/SemaCXX/deprecated.cpp
+++ b/clang/test/SemaCXX/deprecated.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
-// RUN: %clang_cc1 -std=c++11 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
-// RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
-// RUN: %clang_cc1 -std=c++17 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++98 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++11 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++17 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu
// RUN: %clang_cc1 -std=c++2a %s -Wno-parentheses -Wdeprecated -verify=expected,cxx20 -triple x86_64-linux-gnu
-// RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS
+// RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS
#include "Inputs/register.h"
@@ -223,5 +223,32 @@ namespace DeprecatedVolatile {
}
}
+namespace ArithConv {
+ enum E { e } e2;
+ enum F { f };
+ bool b1 = e == e2;
+ bool b2 = e == f; // not-cxx20-warning-re {{
diff erent enumeration types ('ArithConv::E' and 'ArithConv::F'){{$}}}} cxx20-warning {{F') is deprecated}}
+ bool b3 = e == 0.0; // cxx20-warning {{comparison of enumeration type 'ArithConv::E' with floating-point type 'double' is deprecated}}
+ bool b4 = 0.0 == f; // cxx20-warning {{comparison of floating-point type 'double' with enumeration type 'ArithConv::F' is deprecated}}
+ int n1 = true ? e : f; // cxx20-warning {{conditional expression between
diff erent enumeration types ('ArithConv::E' and 'ArithConv::F') is deprecated}}
+ int n2 = true ? e : 0.0; // cxx20-warning {{conditional expression between enumeration type 'ArithConv::E' and floating-point type 'double' is deprecated}}
+}
+
+namespace ArrayComp {
+ int arr1[3], arr2[4];
+ bool b1 = arr1 == arr2; // expected-warning {{array comparison always evaluates to false}} cxx20-warning {{comparison between two arrays is deprecated}}
+ bool b2 = arr1 < arr2; // expected-warning {{array comparison always evaluates to a constant}} cxx20-warning {{comparison between two arrays is deprecated}}
+ __attribute__((weak)) int arr3[3];
+ bool b3 = arr1 == arr3; // cxx20-warning {{comparison between two arrays is deprecated}}
+ bool b4 = arr1 < arr3; // cxx20-warning {{comparison between two arrays is deprecated}}
+#if __cplusplus > 201703L
+ bool b5 = arr1 <=> arr2; // cxx20-error {{invalid operands}}
+#endif
+
+ int (&f())[3];
+ bool b6 = arr1 == f(); // cxx20-warning {{comparison between two arrays is deprecated}}
+ bool b7 = arr1 == +f();
+}
+
# 1 "/usr/include/system-header.h" 1 3
void system_header_function(void) throw();
diff --git a/clang/test/SemaCXX/self-comparison.cpp b/clang/test/SemaCXX/self-comparison.cpp
index 95b830c910f5..72127f110241 100644
--- a/clang/test/SemaCXX/self-comparison.cpp
+++ b/clang/test/SemaCXX/self-comparison.cpp
@@ -15,16 +15,16 @@ struct A {
int b[3];
bool f() { return x == x; } // expected-warning {{self-comparison always evaluates to true}}
bool g() { return x2 == x2; } // no-warning
- bool h() { return a == b; } // expected-warning {{array comparison always evaluates to false}}
+ bool h() { return a == b; } // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}}
bool i() {
int c[3];
- return a == c; // expected-warning {{array comparison always evaluates to false}}
+ return a == c; // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}}
}
};
namespace NA { extern "C" int x[3]; }
namespace NB { extern "C" int x[3]; }
-bool k = NA::x == NB::x; // expected-warning {{self-comparison always evaluates to true}}
+bool k = NA::x == NB::x; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
template<typename T> struct Y { static inline int n; };
bool f() {
@@ -81,7 +81,7 @@ int struct_test(S s1, S s2, S *s3, T t) {
return s2.field == s2.field; // expected-warning {{self-comparison always evaluates to true}}
return s1.static_field == s2.static_field; // expected-warning {{self-comparison always evaluates to true}}
return S::static_field == s1.static_field; // expected-warning {{self-comparison always evaluates to true}}
- return s1.array == s1.array; // expected-warning {{self-comparison always evaluates to true}}
+ return s1.array == s1.array; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
return t.s.static_field == S::static_field; // expected-warning {{self-comparison always evaluates to true}}
return s3->field == s3->field; // expected-warning {{self-comparison always evaluates to true}}
return s3->static_field == S::static_field; // expected-warning {{self-comparison always evaluates to true}}
@@ -102,7 +102,7 @@ int struct_test(S s1, S s2, S *s3, T t) {
// no warning
return s1.field == s2.field;
- return s2.array == s1.array;
+ return s2.array == s1.array; // FIXME: This always evaluates to false. expected-warning {{deprecated}}
return s2.array[0] == s1.array[0];
return s1.array[I1] == s1.array[I2];
diff --git a/clang/test/SemaCXX/warn-enum-compare.cpp b/clang/test/SemaCXX/warn-enum-compare.cpp
index 21dea5dfcb00..eb777b2f6dc7 100644
--- a/clang/test/SemaCXX/warn-enum-compare.cpp
+++ b/clang/test/SemaCXX/warn-enum-compare.cpp
@@ -76,184 +76,184 @@ void test () {
while (td == AnonAA); // expected-warning {{comparison of constant 'AnonAA' (42) with expression of type 'TD' is always false}}
#endif
- while (B1 == B2); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
- while (name1::B2 == name2::B3); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
- while (z == name2::B2); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
-
- while (((((B1)))) == B2); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
- while (name1::B2 == (name2::B3)); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
- while (z == ((((name2::B2))))); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
-
- while ((((B1))) == (((B2)))); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
- while ((name1::B2) == (((name2::B3)))); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
- while ((((z))) == (name2::B2)); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
-
- while (x == a); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'name1::Foo')}}
- while (x == b); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'oneFoo' (aka 'name1::Foo'))}}
- while (x == c); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'twoFoo' (aka 'name1::Foo'))}}
-
- while (x == y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x != y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x >= y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x <= y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x > y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x < y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (FooB == y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB != y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB >= y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB <= y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB > y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB < y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (FooB == BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB != BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB >= BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB <= BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB > BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB < BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (x == BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x != BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x >= BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x <= BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x > BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x < BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (getFoo() == y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() != y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() >= y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() <= y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() > y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() < y); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (getFoo() == BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() != BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() >= BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() <= BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() > BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() < BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (getFoo() == getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() != getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() >= getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() <= getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() > getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (getFoo() < getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (FooB == getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB != getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB >= getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB <= getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB > getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (FooB < getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
- while (x == getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x != getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x >= getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x <= getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x > getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
- while (x < getBar()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'Bar')}}
-
-
-
- while (y == x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y != x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y >= x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y <= x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y > x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y < x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (y == FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y != FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y >= FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y <= FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y > FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y < FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (BarD == FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD != FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD >= FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD <= FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD > FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD <FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (BarD == x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD != x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD >= x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD <= x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD < x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD > x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (y == getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y != getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y >= getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y <= getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y > getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (y < getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (BarD == getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD != getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD >= getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD <= getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD > getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (BarD < getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (getBar() == getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() != getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() >= getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() <= getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() > getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() < getFoo()); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (getBar() == FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() != FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() >= FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() <= FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() > FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() < FooB); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (getBar() == x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() != x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() >= x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() <= x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() > x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
- while (getBar() < x); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'Foo')}}
-
- while (td == FooA); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'Foo')}}
- while (td == BarD); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'Bar')}}
- while (name1::F1 == td); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Foo' and 'TD')}}
- while (name2::B1 == td); // expected-warning {{comparison of two values with
diff erent enumeration types ('name2::Baz' and 'TD')}}
- while (td == a); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'name1::Foo')}}
- while (td == b); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'oneFoo' (aka 'name1::Foo'))}}
- while (td == c); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'twoFoo' (aka 'name1::Foo'))}}
- while (td == x); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'Foo')}}
- while (td == y); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'Bar')}}
- while (td == z); // expected-warning {{comparison of two values with
diff erent enumeration types ('TD' and 'name1::Baz')}}
-
- while (a == TD1); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Foo' and 'TD')}}
- while (b == TD2); // expected-warning {{comparison of two values with
diff erent enumeration types ('oneFoo' (aka 'name1::Foo') and 'TD')}}
- while (c == TD1); // expected-warning {{comparison of two values with
diff erent enumeration types ('twoFoo' (aka 'name1::Foo') and 'TD')}}
- while (x == TD2); // expected-warning {{comparison of two values with
diff erent enumeration types ('Foo' and 'TD')}}
- while (y == TD1); // expected-warning {{comparison of two values with
diff erent enumeration types ('Bar' and 'TD')}}
- while (z == TD2); // expected-warning {{comparison of two values with
diff erent enumeration types ('name1::Baz' and 'TD')}}
+ while (B1 == B2); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+ while (name1::B2 == name2::B3); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+ while (z == name2::B2); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+
+ while (((((B1)))) == B2); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+ while (name1::B2 == (name2::B3)); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+ while (z == ((((name2::B2))))); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+
+ while ((((B1))) == (((B2)))); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+ while ((name1::B2) == (((name2::B3)))); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+ while ((((z))) == (name2::B2)); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'name2::Baz')}}
+
+ while (x == a); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'name1::Foo')}}
+ while (x == b); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'oneFoo' (aka 'name1::Foo'))}}
+ while (x == c); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'twoFoo' (aka 'name1::Foo'))}}
+
+ while (x == y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x != y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x >= y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x <= y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x > y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x < y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (FooB == y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB != y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB >= y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB <= y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB > y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB < y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (FooB == BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB != BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB >= BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB <= BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB > BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB < BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (x == BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x != BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x >= BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x <= BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x > BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x < BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (getFoo() == y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() != y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() >= y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() <= y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() > y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() < y); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (getFoo() == BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() != BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() >= BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() <= BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() > BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() < BarD); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (getFoo() == getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() != getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() >= getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() <= getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() > getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (getFoo() < getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (FooB == getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB != getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB >= getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB <= getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB > getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (FooB < getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+ while (x == getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x != getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x >= getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x <= getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x > getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+ while (x < getBar()); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'Bar')}}
+
+
+
+ while (y == x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y != x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y >= x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y <= x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y > x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y < x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (y == FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y != FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y >= FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y <= FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y > FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y < FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (BarD == FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD != FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD >= FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD <= FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD > FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD <FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (BarD == x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD != x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD >= x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD <= x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD < x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD > x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (y == getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y != getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y >= getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y <= getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y > getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (y < getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (BarD == getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD != getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD >= getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD <= getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD > getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (BarD < getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (getBar() == getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() != getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() >= getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() <= getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() > getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() < getFoo()); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (getBar() == FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() != FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() >= FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() <= FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() > FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() < FooB); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (getBar() == x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() != x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() >= x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() <= x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() > x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+ while (getBar() < x); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'Foo')}}
+
+ while (td == FooA); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'Foo')}}
+ while (td == BarD); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'Bar')}}
+ while (name1::F1 == td); // expected-warning {{comparison of
diff erent enumeration types ('name1::Foo' and 'TD')}}
+ while (name2::B1 == td); // expected-warning {{comparison of
diff erent enumeration types ('name2::Baz' and 'TD')}}
+ while (td == a); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'name1::Foo')}}
+ while (td == b); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'oneFoo' (aka 'name1::Foo'))}}
+ while (td == c); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'twoFoo' (aka 'name1::Foo'))}}
+ while (td == x); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'Foo')}}
+ while (td == y); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'Bar')}}
+ while (td == z); // expected-warning {{comparison of
diff erent enumeration types ('TD' and 'name1::Baz')}}
+
+ while (a == TD1); // expected-warning {{comparison of
diff erent enumeration types ('name1::Foo' and 'TD')}}
+ while (b == TD2); // expected-warning {{comparison of
diff erent enumeration types ('oneFoo' (aka 'name1::Foo') and 'TD')}}
+ while (c == TD1); // expected-warning {{comparison of
diff erent enumeration types ('twoFoo' (aka 'name1::Foo') and 'TD')}}
+ while (x == TD2); // expected-warning {{comparison of
diff erent enumeration types ('Foo' and 'TD')}}
+ while (y == TD1); // expected-warning {{comparison of
diff erent enumeration types ('Bar' and 'TD')}}
+ while (z == TD2); // expected-warning {{comparison of
diff erent enumeration types ('name1::Baz' and 'TD')}}
switch (a) {
case name1::F1: break;
case name1::F3: break;
- case name2::B2: break; // expected-warning {{comparison of two values with
diff erent enumeration types in switch statement ('name1::Foo' and 'name2::Baz')}}
+ case name2::B2: break; // expected-warning {{comparison of
diff erent enumeration types in switch statement ('name1::Foo' and 'name2::Baz')}}
}
switch (x) {
case FooB: break;
case FooC: break;
- case BarD: break; // expected-warning {{comparison of two values with
diff erent enumeration types in switch statement ('Foo' and 'Bar')}}
+ case BarD: break; // expected-warning {{comparison of
diff erent enumeration types in switch statement ('Foo' and 'Bar')}}
}
switch(getBar()) {
case BarE: break;
case BarF: break;
- case FooA: break; // expected-warning {{comparison of two values with
diff erent enumeration types in switch statement ('Bar' and 'Foo')}}
+ case FooA: break; // expected-warning {{comparison of
diff erent enumeration types in switch statement ('Bar' and 'Foo')}}
}
switch(x) {
@@ -265,8 +265,8 @@ void test () {
switch (td) {
case TD1: break;
- case FooB: break; // expected-warning {{comparison of two values with
diff erent enumeration types in switch statement ('TD' and 'Foo')}}
- case BarF: break; // expected-warning {{comparison of two values with
diff erent enumeration types in switch statement ('TD' and 'Bar')}}
+ case FooB: break; // expected-warning {{comparison of
diff erent enumeration types in switch statement ('TD' and 'Foo')}}
+ case BarF: break; // expected-warning {{comparison of
diff erent enumeration types in switch statement ('TD' and 'Bar')}}
// expected-warning at -1 {{case value not in enumerated type 'TD'}}
case AnonAA: break; // expected-warning {{case value not in enumerated type 'TD'}}
}
@@ -277,8 +277,8 @@ void test () {
}
switch (a) {
- case TD1: break; // expected-warning {{comparison of two values with
diff erent enumeration types in switch statement ('name1::Foo' and 'TD')}}
- case TD2: break; // expected-warning {{comparison of two values with
diff erent enumeration types in switch statement ('name1::Foo' and 'TD')}}
+ case TD1: break; // expected-warning {{comparison of
diff erent enumeration types in switch statement ('name1::Foo' and 'TD')}}
+ case TD2: break; // expected-warning {{comparison of
diff erent enumeration types in switch statement ('name1::Foo' and 'TD')}}
case name1::F3: break;
}
}
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 3f7cfd1308bf..0829a2b1298b 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -926,18 +926,16 @@ <h2 id="cxx20">C++2a implementation status</h2>
<tr>
<td rowspan="8">Consistent comparison (<tt>operator<=></tt>)</td>
<td><a href="https://wg21.link/p0515r3">P0515R3</a></td>
- <td rowspan="2" class="svn" align="center">SVN</td>
+ <td rowspan="7" class="svn" align="center">SVN</td>
</tr>
<tr> <!-- from Jacksonville -->
<td><a href="https://wg21.link/p0905r1">P0905R1</a></td>
</tr>
<tr> <!-- from Rapperswil -->
<td><a href="https://wg21.link/p1120r0">P1120R0</a></td>
- <td class="partial" align="center">Partial</td>
</tr>
<tr> <!-- from Kona 2019 -->
<td><a href="https://wg21.link/p1185r2">P1185R2</a></td>
- <td rowspan="4" class="svn" align="center">SVN</td>
</tr>
<tr> <!-- from Cologne -->
<td><a href="https://wg21.link/p1186r3">P1186R3</a></td>
More information about the cfe-commits
mailing list