Author: Sirraide Date: 2026-07-15T19:49:29Z New Revision: 0b18869a684febeb4144cd0213cef3163b8cb37e
URL: https://github.com/llvm/llvm-project/commit/0b18869a684febeb4144cd0213cef3163b8cb37e DIFF: https://github.com/llvm/llvm-project/commit/0b18869a684febeb4144cd0213cef3163b8cb37e.diff LOG: [Clang] [Diagnostic] Extend DiagCompat() to C language modes (#209241) This expands the compatibility warnings infrastructure added in #132348 to support C mode as well. Implementing this was actually fairly straight-forward because we are only ever in C _or_ C++ mode, i.e. during a single compilation we either emit only C compatibility warnings or only C++ compatibility warnings. This means we can simply reuse the existing code and just check for different LangOpts depending on whether we're in C or C++ mode. Concretely, this means that instead of e.g. ``` def ext_c2y_alignof_incomplete_array : Extension< "'alignof' on an incomplete array type is a C2y extension">, InGroup<C2y>; def warn_c2y_compat_alignof_incomplete_array : Warning< "'alignof' on an incomplete array type is incompatible with C standards " "before C2y">, InGroup<CPre2yCompat>, DefaultIgnore; ``` you can now simply write ``` defm alignof_incomplete_array : C2yCompat<"'alignof' on an incomplete array type is">; ``` And when emitting the warning(s), code such as ``` Diag(OpLoc, getLangOpts().C2y ? diag::warn_c2y_compat_alignof_incomplete_array : diag::ext_c2y_alignof_incomplete_array); ``` can now be replaced with ``` DiagCompat(OpLoc, diag_compat::alignof_incomplete_array); ``` I've also migrated the C compatibility warnings in DiagnosticSemaKinds.td to use the new system to make sure that everything is working properly. Added: Modified: clang/bindings/python/tests/cindex/test_diagnostics.py clang/include/clang/Basic/Diagnostic.td clang/include/clang/Basic/DiagnosticIDs.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Basic/DiagnosticIDs.cpp clang/lib/Parse/Parser.cpp clang/lib/Sema/SemaBase.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaStmt.cpp clang/lib/Sema/SemaType.cpp Removed: ################################################################################ diff --git a/clang/bindings/python/tests/cindex/test_diagnostics.py b/clang/bindings/python/tests/cindex/test_diagnostics.py index 17c1a4e50a20c..6e5d8b525028a 100644 --- a/clang/bindings/python/tests/cindex/test_diagnostics.py +++ b/clang/bindings/python/tests/cindex/test_diagnostics.py @@ -75,7 +75,7 @@ def test_diagnostic_category(self): self.assertEqual(d.location.line, 1) self.assertEqual(d.location.column, 11) - self.assertEqual(d.category_number, 3) + self.assertEqual(d.category_number, 2) self.assertEqual(d.category_name, "Semantic Issue") def test_diagnostic_option(self): @@ -119,7 +119,7 @@ def test_diagnostic_string_format(self): self.assertEqual(str(d), "t.c:1:26: error: expected ';' after struct") self.assertEqual( d.format(0b111111), - "t.c:1:26: error: expected ';' after struct [2, Parse Issue]", + "t.c:1:26: error: expected ';' after struct [3, Parse Issue]", ) with self.assertRaises(ValueError): d.format(0b1000000) diff --git a/clang/include/clang/Basic/Diagnostic.td b/clang/include/clang/Basic/Diagnostic.td index 693984d8241f0..4477828c05eda 100644 --- a/clang/include/clang/Basic/Diagnostic.td +++ b/clang/include/clang/Basic/Diagnostic.td @@ -191,60 +191,80 @@ class CompatWarningId<string name, int std, string diag, string diag_pre> { string CategoryName = ?; } -// C++ compatibility warnings. -multiclass CXXCompat< +// Compatibility warnings. +multiclass CompatWarning< + // Diagnostic message. string message, + // Version number. int std_ver, + // Is this C++? + bit cxx, + // ExtWarn if true, Extension if false. bit ext_warn = true, - string std_ver_override = ""#std_ver> { - // 'X is a C++YZ extension'. - def compat_pre_cxx#std_ver#_#NAME : - Diagnostic<!strconcat(message, " a C++", std_ver_override, " extension"), + // Language mode name to use in the diagnostic text. + string std_ver_name = ""#std_ver, + // Version string used in diagnostic group names. + string diag_group_ver_str = ""#std_ver> { + defvar lang = !if(cxx, "C++", "C"); + defvar prefix = !if(cxx, "CXX", "C"); + defvar prefix_lower = !tolower(prefix#diag_group_ver_str); + defvar is_cxx_11 = !and(cxx, !eq(std_ver, 11)); + + // 'X is a C(++)YZ extension'. + def compat_pre_#prefix_lower#_#NAME : + Diagnostic<!strconcat(message, " a ", lang, std_ver_name, " extension"), CLASS_EXTENSION, !if(ext_warn, SEV_Warning, SEV_Ignored)>, - InGroup<!cast<DiagGroup>("CXX"#std_ver)>; + InGroup<!cast<DiagGroup>(prefix#diag_group_ver_str)>; - // 'X is incompatible with C++98' (if std_ver == 11). - // 'X is incompatible with C++ standards before C++YZ' (otherwise). - def compat_cxx#std_ver#_#NAME : - Warning<!if(!eq(std_ver, 11), + // 'X is incompatible with C++98' (if is_cxx_11 is true). + // 'X is incompatible with C(++) standards before C(++)YZ' (otherwise). + def compat_#prefix_lower#_#NAME : + Warning<!if(is_cxx_11, !strconcat(message, " incompatible with C++98"), - !strconcat(message, " incompatible with C++ standards before C++", std_ver_override))>, - InGroup<!cast<DiagGroup>(!if(!eq(std_ver, 11), - "CXX98Compat", - "CXXPre"#std_ver#"Compat"))>, + !strconcat(message, " incompatible with ", lang, " standards before ", lang, std_ver_name))>, + InGroup<!cast<DiagGroup>(!if(is_cxx_11, + prefix#"98Compat", + prefix#"Pre"#diag_group_ver_str#"Compat"))>, DefaultIgnore; def : CompatWarningId< NAME, std_ver, - "compat_cxx"#std_ver#"_"#NAME, - "compat_pre_cxx"#std_ver#"_"#NAME>; + "compat_"#prefix_lower#"_"#NAME, + "compat_pre_"#prefix_lower#"_"#NAME>; } -// These generate pairs of C++ compatibility warnings of the form: +// These generate pairs of C(++) compatibility warnings of the form: // -// - compat_cxx<std>_<name> -// - compat_pre_cxx<std>_<name> +// - compat_c(xx)<std>_<name> +// - compat_pre_c(xx)<std>_<name> // -// The 'compat_cxx...' warning is intended to be issued in C++<std> mode, -// and the 'compat_pre_cxx...' warning in C++ modes before C++<std>. +// The 'compat_c(xx)...' warning is intended to be issued in C(++)<std> mode, +// and the 'compat_pre_c(xx)...' warning in C(++) modes before C(++)<std>. // // Example: // -// defm inline_variable : CXX17Compat<"inline variables are">; +// defm inline_variable : C(XX)11Compat<"inline variables are">; // // This generates two warnings: // -// - compat_cxx17_inline_variable: 'inline variables are incompatible with C++ standards before C++17' -// - compat_pre_cxx17_inline_variable: 'inline variables are a C++17 extension' +// - compat_c(xx)11_inline_variable: 'inline variables are incompatible with C(++) standards before C(++)11' +// - compat_pre_c(xx)11_inline_variable: 'inline variables are a C(++)11 extension' // -multiclass CXX11Compat<string message, bit ext_warn = true> : CXXCompat<message, 11, ext_warn>; -multiclass CXX14Compat<string message, bit ext_warn = true> : CXXCompat<message, 14, ext_warn>; -multiclass CXX17Compat<string message, bit ext_warn = true> : CXXCompat<message, 17, ext_warn>; -multiclass CXX20Compat<string message, bit ext_warn = true> : CXXCompat<message, 20, ext_warn>; -multiclass CXX23Compat<string message, bit ext_warn = true> : CXXCompat<message, 23, ext_warn>; -multiclass CXX26Compat<string message, bit ext_warn = true> : CXXCompat<message, 26, ext_warn, "2c">; -multiclass CXX29Compat<string message, bit ext_warn = true> : CXXCompat<message, 29, ext_warn, "2d">; +multiclass CXX11Compat<string message, bit ext_warn = true> : CompatWarning<message, 11, /*cxx=*/true, ext_warn>; +multiclass CXX14Compat<string message, bit ext_warn = true> : CompatWarning<message, 14, /*cxx=*/true, ext_warn>; +multiclass CXX17Compat<string message, bit ext_warn = true> : CompatWarning<message, 17, /*cxx=*/true, ext_warn>; +multiclass CXX20Compat<string message, bit ext_warn = true> : CompatWarning<message, 20, /*cxx=*/true, ext_warn>; +multiclass CXX23Compat<string message, bit ext_warn = true> : CompatWarning<message, 23, /*cxx=*/true, ext_warn>; +multiclass CXX26Compat<string message, bit ext_warn = true> : CompatWarning<message, 26, /*cxx=*/true, ext_warn, "2c">; +multiclass CXX29Compat<string message, bit ext_warn = true> : CompatWarning<message, 29, /*cxx=*/true, ext_warn, "2d">; + +// C compatibility warnings generally use Extension rather than ExtWarn. +multiclass C99Compat<string message, bit ext_warn = false> : CompatWarning<message, 99, /*cxx=*/false, ext_warn>; +multiclass C11Compat<string message, bit ext_warn = false> : CompatWarning<message, 11, /*cxx=*/false, ext_warn>; +multiclass C17Compat<string message, bit ext_warn = false> : CompatWarning<message, 17, /*cxx=*/false, ext_warn>; +multiclass C23Compat<string message, bit ext_warn = false> : CompatWarning<message, 23, /*cxx=*/false, ext_warn>; +multiclass C2yCompat<string message, bit ext_warn = false> : CompatWarning<message, 29, /*cxx=*/false, ext_warn, "2y", "2y">; // Definitions for Diagnostics. include "DiagnosticASTKinds.td" diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h index 63b5e6a28aac0..f71e47b5cba70 100644 --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -485,8 +485,8 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> { /// Get the appropriate diagnostic Id to use for issuing a compatibility /// diagnostic. For use by the various DiagCompat() helpers. - static unsigned getCXXCompatDiagId(const LangOptions &LangOpts, - unsigned CompatDiagId); + static unsigned getCompatDiagId(const LangOptions &LangOpts, + unsigned CompatDiagId); /// Return true if either of the following two conditions hold: /// 1. \p Loc is in a system header and the diagnostic kind \p DiagID does diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b6a38b9e281dc..f14288dd2967d 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12,6 +12,17 @@ let Component = "Sema" in { let CategoryName = "Semantic Issue" in { +// C23 compatibility with C17. +defm restrict_on_array_of_pointers : C23Compat<"'restrict' qualifier on an array of pointers is">; +defm non_local_variable_decl_in_for : C23Compat<"declaration of non-local variable in 'for' loop is">; +defm non_variable_decl_in_for : C23Compat<"non-variable declaration in 'for' loop is">; + +// C2y compatibility with C23. +defm imaginary_constant : C2yCompat<"imaginary constants are">; +defm alignof_incomplete_array : C2yCompat<"'alignof' on an incomplete array type is">; +defm increment_complex : C2yCompat<"'%select{--|++}0' on an object of complex type is">; +defm assoc_type_incomplete : C2yCompat<"use of incomplete type %0 in a '_Generic' association is">; + // C++11 compatibility with C++98. defm nonclass_type_friend : CXX11Compat<"non-class friend type %0 is">; defm static_data_member_in_union : CXX11Compat<"static data member %0 in union is">; @@ -66,8 +77,9 @@ defm decomp_decl_cond : CXX26Compat<"structured binding declaration in a conditi // Compatibility warnings duplicated across multiple language versions. foreach std = [14, 20, 23] in { - defm cxx#std#_constexpr_body_invalid_stmt : CXXCompat< - "use of this statement in a constexpr %select{function|constructor}0 is", std>; + defm cxx#std#_constexpr_body_invalid_stmt : CompatWarning< + "use of this statement in a constexpr %select{function|constructor}0 is", + std, /*cxx=*/true>; } def note_previous_decl : Note<"%0 declared here">; @@ -322,11 +334,6 @@ def ext_designated_init_brace_elision : ExtWarn< // Declarations. def ext_plain_complex : ExtWarn< "plain '_Complex' requires a type specifier; assuming '_Complex double'">; -def warn_c23_compat_imaginary_constant : Warning< - "imaginary constants are incompatible with C standards before C2y">, - DefaultIgnore, InGroup<CPre2yCompat>; -def ext_c2y_imaginary_constant : Extension< - "imaginary constants are a C2y extension">, InGroup<C2y>; def ext_gnu_imaginary_constant : Extension< "imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>; def ext_integer_complex : Extension< @@ -3826,12 +3833,6 @@ def warn_alignment_not_power_of_two : Warning< InGroup<DiagGroup<"non-power-of-two-alignment">>; def err_alignment_dependent_typedef_name : Error< "requested alignment is dependent but declaration is not dependent">; -def ext_c2y_alignof_incomplete_array : Extension< - "'alignof' on an incomplete array type is a C2y extension">, - InGroup<C2y>; -def warn_c2y_compat_alignof_incomplete_array : Warning< - "'alignof' on an incomplete array type is incompatible with C standards " - "before C2y">, InGroup<CPre2yCompat>, DefaultIgnore; def warn_alignment_builtin_useless : Warning< "%select{aligning a value|the result of checking whether a value is aligned}0" @@ -7912,11 +7913,6 @@ def warn_c23_compat_utf8_string : Warning< def note_cxx20_c23_compat_utf8_string_remove_u8 : Note< "remove 'u8' prefix to avoid a change of behavior; " "Clang encodes unprefixed narrow string literals as UTF-8">; -def warn_c23_compat_restrict_on_array_of_pointers : Warning< - "'restrict' qualifier on an array of pointers is incompatible with C standards before C23">, - InGroup<CPre23Compat>, DefaultIgnore; -def ext_restrict_on_array_of_pointers_c23 : Extension< - "'restrict' qualifier on an array of pointers is a C23 extension">, InGroup<C23>; def err_array_init_ diff erent_type : Error< "cannot initialize array % diff {of type $ with array of type $|" "with diff erent type of array}0,1">; @@ -8365,12 +8361,6 @@ def note_gnu_counted_by_void_ptr_use_sized_by "to suppress this warning">; def err_readonly_message_assignment : Error< "assigning to 'readonly' return result of an Objective-C message not allowed">; -def ext_c2y_increment_complex : Extension< - "'%select{--|++}0' on an object of complex type is a C2y extension">, - InGroup<C2y>; -def warn_c2y_compat_increment_complex : Warning< - "'%select{--|++}0' on an object of complex type is incompatible with C " - "standards before C2y">, InGroup<CPre2yCompat>, DefaultIgnore; def ext_integer_complement_complex : Extension< "ISO C does not support '~' for complex conjugation of %0">; def err_nosetter_property_assignment : Error< @@ -11218,13 +11208,6 @@ def warn_type_safety_null_pointer_required : Warning< "specified %0 type tag requires a null pointer">, InGroup<TypeSafety>; // Generic selections. -def ext_assoc_type_incomplete : Extension< - "incomplete type %0 in a '_Generic' association is a C2y extension">, - InGroup<C2y>; -def warn_c2y_compat_assoc_type_incomplete : Warning< - "use of incomplete type %0 in a '_Generic' association is incompatible with " - "C standards before C2y">, - InGroup<CPre2yCompat>, DefaultIgnore; def err_assoc_type_nonobject : Error< "type %0 in generic association not an object type">; def err_assoc_type_variably_modified : Error< @@ -11619,22 +11602,6 @@ def err_non_local_variable_decl_in_for : Error< def err_non_variable_decl_in_for : Error< "non-variable declaration in 'for' loop">; -def ext_c23_non_local_variable_decl_in_for : Extension< - "declaration of non-local variable in 'for' loop is a C23 extension">, - InGroup<C23>; - -def warn_c17_non_local_variable_decl_in_for : Warning< - "declaration of non-local variable in 'for' loop is incompatible with C standards before C23">, - DefaultIgnore, InGroup<CPre23Compat>; - -def ext_c23_non_variable_decl_in_for : Extension< - "non-variable declaration in 'for' loop is a C23 extension">, - InGroup<C23>; - -def warn_c17_non_variable_decl_in_for : Warning< - "non-variable declaration in 'for' loop is incompatible with C standards before C23">, - DefaultIgnore, InGroup<CPre23Compat>; - def err_toomany_element_decls : Error< "only one element declaration is allowed">; def err_selector_element_not_lvalue : Error< diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index 6445aa6f4ecb1..92f96d1b9ad90 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -876,8 +876,8 @@ StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor, return Best; } -unsigned DiagnosticIDs::getCXXCompatDiagId(const LangOptions &LangOpts, - unsigned CompatDiagId) { +unsigned DiagnosticIDs::getCompatDiagId(const LangOptions &LangOpts, + unsigned CompatDiagId) { struct CompatDiag { unsigned StdVer; unsigned DiagId; @@ -888,10 +888,17 @@ unsigned DiagnosticIDs::getCXXCompatDiagId(const LangOptions &LangOpts, // actual numbers don't really matter for this, but the definitions of the // compat diags in the Tablegen file use the standard version number (i.e. // 98, 11, 14, etc.), so we base the encoding here on that. + // + // Likewise, for C, we have C99 < C11 < C17 < C23 < C29. + // + // We do end up with some overlap between C and C++ here, e.g. 2011 is used + // for both C11 and C++11, but this doesn't matter since we're never in e.g. + // C11 and C++11 mode at the same time (additionally, we should only ever + // be issuing C compatibility diagnostics in C mode and likewise for C++). #define DIAG_COMPAT_IDS_BEGIN() #define DIAG_COMPAT_IDS_END() #define DIAG_COMPAT_ID(Value, Name, Std, Diag, DiagPre) \ - {Std == 98 ? 1998 : 2000 + Std, diag::Diag, diag::DiagPre}, + {Std >= 98 ? 1900 + Std : 2000 + Std, diag::Diag, diag::DiagPre}, static constexpr CompatDiag Diags[]{ #include "clang/Basic/DiagnosticAllCompatIDs.inc" }; @@ -902,6 +909,20 @@ unsigned DiagnosticIDs::getCXXCompatDiagId(const LangOptions &LangOpts, assert(CompatDiagId < std::size(Diags) && "Invalid compat diag id"); unsigned StdVer = [&] { + if (!LangOpts.CPlusPlus) { + if (LangOpts.C2y) + return 2029; + if (LangOpts.C23) + return 2023; + if (LangOpts.C17) + return 2017; + if (LangOpts.C11) + return 2011; + if (LangOpts.C99) + return 1999; + return 1989; + } + if (LangOpts.CPlusPlus29) return 2029; if (LangOpts.CPlusPlus26) diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 5e1fd4df1a3f0..f30cd68bf1e6c 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -95,8 +95,7 @@ DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) { DiagnosticBuilder Parser::DiagCompat(SourceLocation Loc, unsigned CompatDiagId) { - return Diag(Loc, - DiagnosticIDs::getCXXCompatDiagId(getLangOpts(), CompatDiagId)); + return Diag(Loc, DiagnosticIDs::getCompatDiagId(getLangOpts(), CompatDiagId)); } DiagnosticBuilder Parser::DiagCompat(const Token &Tok, unsigned CompatDiagId) { diff --git a/clang/lib/Sema/SemaBase.cpp b/clang/lib/Sema/SemaBase.cpp index 5524ff50fce85..e16ec2883b89c 100644 --- a/clang/lib/Sema/SemaBase.cpp +++ b/clang/lib/Sema/SemaBase.cpp @@ -97,7 +97,6 @@ Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, SemaBase::SemaDiagnosticBuilder SemaBase::DiagCompat(SourceLocation Loc, unsigned CompatDiagId) { - return Diag(Loc, - DiagnosticIDs::getCXXCompatDiagId(getLangOpts(), CompatDiagId)); + return Diag(Loc, DiagnosticIDs::getCompatDiagId(getLangOpts(), CompatDiagId)); } } // namespace clang diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6d7cdf9f60dea..b844670543a55 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1924,8 +1924,8 @@ ExprResult Sema::CreateGenericSelectionExpr( // earlier because GCC does so. unsigned D = 0; if (ControllingExpr && Types[i]->getType()->isIncompleteType()) - D = LangOpts.C2y ? diag::warn_c2y_compat_assoc_type_incomplete - : diag::ext_assoc_type_incomplete; + D = LangOpts.C2y ? diag::compat_c2y_assoc_type_incomplete + : diag::compat_pre_c2y_assoc_type_incomplete; else if (ControllingExpr && !Types[i]->getType()->isObjectType()) D = diag::err_assoc_type_nonobject; else if (Types[i]->getType()->isVariablyModifiedType()) @@ -4260,14 +4260,10 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Context.getComplexType(Res->getType())); // In C++, this is a GNU extension. In C, it's a C2y extension. - unsigned DiagId; if (getLangOpts().CPlusPlus) - DiagId = diag::ext_gnu_imaginary_constant; - else if (getLangOpts().C2y) - DiagId = diag::warn_c23_compat_imaginary_constant; + Diag(Tok.getLocation(), diag::ext_gnu_imaginary_constant); else - DiagId = diag::ext_c2y_imaginary_constant; - Diag(Tok.getLocation(), DiagId); + DiagCompat(Tok.getLocation(), diag_compat::imaginary_constant); } return Res; } @@ -4734,9 +4730,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType, // trait to an incomplete array is an extension. if (ExprKind == UETT_AlignOf && !getLangOpts().CPlusPlus && ExprType->isIncompleteArrayType()) - Diag(OpLoc, getLangOpts().C2y - ? diag::warn_c2y_compat_alignof_incomplete_array - : diag::ext_c2y_alignof_incomplete_array); + DiagCompat(OpLoc, diag_compat::alignof_incomplete_array); ExprType = Context.getBaseElementType(ExprType); } @@ -14824,8 +14818,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, return QualType(); } else if (ResType->isAnyComplexType()) { // C99 does not support ++/-- on complex types, we allow as an extension. - S.Diag(OpLoc, S.getLangOpts().C2y ? diag::warn_c2y_compat_increment_complex - : diag::ext_c2y_increment_complex) + S.DiagCompat(OpLoc, diag_compat::increment_complex) << IsInc << Op->getSourceRange(); } else if (ResType->isPlaceholderType()) { ExprResult PR = S.CheckPlaceholderExpr(Op); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index e6afcd4404501..cc325620883f0 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2293,10 +2293,8 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, if (VarDecl *VD = dyn_cast<VarDecl>(DI)) { VarDeclSeen = true; if (VD->isLocalVarDecl() && !VD->hasLocalStorage()) - Diag(DI->getLocation(), - getLangOpts().C23 - ? diag::warn_c17_non_local_variable_decl_in_for - : diag::ext_c23_non_local_variable_decl_in_for); + DiagCompat(DI->getLocation(), + diag_compat::non_local_variable_decl_in_for); } else if (!NonVarSeen) { // Keep track of the first non-variable declaration we saw so that // we can diagnose if we don't see any variable declarations. This @@ -2312,9 +2310,8 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, // Diagnose if we saw a non-variable declaration but no variable // declarations. if (NonVarSeen && !VarDeclSeen) - Diag(NonVarSeen->getLocation(), - getLangOpts().C23 ? diag::warn_c17_non_variable_decl_in_for - : diag::ext_c23_non_variable_decl_in_for); + DiagCompat(NonVarSeen->getLocation(), + diag_compat::non_variable_decl_in_for); } } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 28ff271531a56..5161db6ac1a99 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1651,9 +1651,7 @@ QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc, Qs.removeRestrict(); } else { if (T->isArrayType()) - Diag(Loc, getLangOpts().C23 - ? diag::warn_c23_compat_restrict_on_array_of_pointers - : diag::ext_restrict_on_array_of_pointers_c23); + DiagCompat(Loc, diag_compat::restrict_on_array_of_pointers); } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
