https://github.com/cor3ntin created https://github.com/llvm/llvm-project/pull/139396
In C++, defaulted to an error. C++ removed these features but the removal negatively impacts users. Fixes #92340 >From 77918bb5b44cf0d319f0948030d9291996f3e5ac Mon Sep 17 00:00:00 2001 From: cor3ntin <corentinja...@gmail.com> Date: Tue, 18 Mar 2025 16:45:37 +0100 Subject: [PATCH] [Clang] Demote mixed enumeration arithmetic error to a warning (#131811) In C++, defaulted to an error. C++ removed these features but the removal negatively impacts users. Fixes #92340 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 +++++- clang/lib/Sema/SemaChecking.cpp | 16 +++++++++++++++- clang/lib/Sema/SemaExpr.cpp | 4 ++-- clang/test/SemaCXX/cxx2c-enum-compare.cpp | 5 +++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ec2a140e04d5b..6c93a46d8f36c 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7567,9 +7567,13 @@ def warn_arith_conv_mixed_enum_types_cxx20 : Warning< "%sub{select_arith_conv_kind}0 " "different enumeration types%diff{ ($ and $)|}1,2 is deprecated">, InGroup<DeprecatedEnumEnumConversion>; -def err_conv_mixed_enum_types_cxx26 : Error< + +def err_conv_mixed_enum_types: Error < "invalid %sub{select_arith_conv_kind}0 " "different enumeration types%diff{ ($ and $)|}1,2">; +def warn_conv_mixed_enum_types_cxx26 : Warning < + err_conv_mixed_enum_types.Summary>, + InGroup<EnumEnumConversion>, DefaultError; def warn_arith_conv_mixed_anon_enum_types : Warning< warn_arith_conv_mixed_enum_types.Summary>, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e440f60526bb3..00f7f87838cf1 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14688,7 +14688,21 @@ bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) { return false; } -bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) { +static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, + SourceLocation Loc) { + QualType L = LHS->getEnumCoercedType(S.Context), + R = RHS->getEnumCoercedType(S.Context); + if (L->isUnscopedEnumerationType() && R->isUnscopedEnumerationType() && + !S.Context.hasSameUnqualifiedType(L, R)) { + return S.Diag(Loc, diag::err_conv_mixed_enum_types) + << LHS->getSourceRange() << RHS->getSourceRange() + << /*Arithmetic Between*/ 0 << L << R; + } + return false; +} + +std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall, + bool FPOnly) { if (checkArgCount(TheCall, 2)) return true; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e253e3a17328f..eae7f1c3aa781 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1518,8 +1518,8 @@ static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS, unsigned DiagID; // In C++ 26, usual arithmetic conversions between 2 different enum types // are ill-formed. - if (S.getLangOpts().CPlusPlus26) - DiagID = diag::err_conv_mixed_enum_types_cxx26; + if (getLangOpts().CPlusPlus26) + DiagID = diag::warn_conv_mixed_enum_types_cxx26; else if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() || !R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) { // If either enumeration type is unnamed, it's less likely that the diff --git a/clang/test/SemaCXX/cxx2c-enum-compare.cpp b/clang/test/SemaCXX/cxx2c-enum-compare.cpp index f47278a60725e..96fbd368b1696 100644 --- a/clang/test/SemaCXX/cxx2c-enum-compare.cpp +++ b/clang/test/SemaCXX/cxx2c-enum-compare.cpp @@ -1,9 +1,10 @@ -// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -verify -triple %itanium_abi_triple +// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -verify=both,expected +// RUN: %clang_cc1 %s -std=c++2c -fsyntax-only -verify=both -Wno-enum-enum-conversion enum E1 { e }; enum E2 { f }; void test() { - int b = e <= 3.7; // expected-error {{invalid comparison of enumeration type 'E1' with floating-point type 'double'}} + int b = e <= 3.7; // both-error {{invalid comparison of enumeration type 'E1' with floating-point type 'double'}} int k = f - e; // expected-error {{invalid arithmetic between different enumeration types ('E2' and 'E1')}} int x = 1 ? e : f; // expected-error {{invalid conditional expression between different enumeration types ('E1' and 'E2')}} } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits