llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) <details> <summary>Changes</summary> This adds a new diagnostic to warn about redeclaration of a tentative definition in C. This is incompatible with C++, so the new diagnostic group is under -Wc++-compat. --- Full diff: https://github.com/llvm/llvm-project/pull/137967.diff 6 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+9) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+3-1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3) - (modified) clang/lib/Sema/SemaDecl.cpp (+3) - (modified) clang/test/Sema/warn-default-const-init.c (+1-1) - (added) clang/test/Sema/warn-tentative-defn-compat.c (+23) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index bc68bb8b70b3d..0c667745f2613 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -171,6 +171,15 @@ C Language Changes ``-Wenum-conversion`` and ``-Wimplicit-int-enum-cast``. This conversion is an int-to-enum conversion because the enumeration on the right-hand side is promoted to ``int`` before the assignment. +- Added ``-Wtentative-definition-compat``, grouped under ``-Wc++-compat``, + which diagnoses tentative definitions in C with multiple declarations as + being incompatible with C++. e.g., + + .. code-block:: c + + // File scope + int i; + int i; // Vaild C, invalid C++, now diagnosed C2y Feature Support ^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index fc1ce197ef134..0ac7b2d39d12e 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -162,8 +162,10 @@ def DefaultConstInit : DiagGroup<"default-const-init", [DefaultConstInitUnsafe]> def ImplicitVoidPtrCast : DiagGroup<"implicit-void-ptr-cast">; def ImplicitIntToEnumCast : DiagGroup<"implicit-int-enum-cast", [ImplicitEnumEnumCast]>; +def TentativeDefnCompat : DiagGroup<"tentative-definition-compat">; def CXXCompat: DiagGroup<"c++-compat", [ImplicitVoidPtrCast, DefaultConstInit, - ImplicitIntToEnumCast, HiddenCppDecl]>; + ImplicitIntToEnumCast, HiddenCppDecl, + TentativeDefnCompat]>; def ExternCCompat : DiagGroup<"extern-c-compat">; def KeywordCompat : DiagGroup<"keyword-compat">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ad5bf26be2590..7cba120cbd924 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7443,6 +7443,9 @@ def err_tentative_def_incomplete_type : Error< def warn_tentative_incomplete_array : Warning< "tentative array definition assumed to have one element">, InGroup<DiagGroup<"tentative-definition-array">>; +def warn_cxx_compat_tentative_definition : Warning< + "duplicate declaration of %0 is invalid in C++">, + InGroup<TentativeDefnCompat>, DefaultIgnore; def err_typecheck_incomplete_array_needs_initializer : Error< "definition of variable with array type needs an explicit size " "or an initializer">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index dfc718eedc1d9..3789eff818e08 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4750,6 +4750,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { if (Def && checkVarDeclRedefinition(Def, New)) return; } + } else { + Diag(New->getLocation(), diag::warn_cxx_compat_tentative_definition) << New; + Diag(Old->getLocation(), diag::note_previous_declaration); } if (haveIncompatibleLanguageLinkages(Old, New)) { diff --git a/clang/test/Sema/warn-default-const-init.c b/clang/test/Sema/warn-default-const-init.c index b8da41b333f3d..ed211e366428e 100644 --- a/clang/test/Sema/warn-default-const-init.c +++ b/clang/test/Sema/warn-default-const-init.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wdefault-const-init %s -// RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wc++-compat %s +// RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wc++-compat -Wno-tentative-definition-compat %s // RUN: %clang_cc1 -fsyntax-only -verify=unsafe %s // RUN: %clang_cc1 -fsyntax-only -verify=c -Wdefault-const-init -Wno-default-const-init-unsafe %s // RUN: %clang_cc1 -fsyntax-only -verify=good -Wno-default-const-init-unsafe %s diff --git a/clang/test/Sema/warn-tentative-defn-compat.c b/clang/test/Sema/warn-tentative-defn-compat.c new file mode 100644 index 0000000000000..02f3db99992f1 --- /dev/null +++ b/clang/test/Sema/warn-tentative-defn-compat.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wtentative-definition-compat %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wc++-compat %s +// RUN: %clang_cc1 -fsyntax-only -verify=good %s +// RUN: %clang_cc1 -fsyntax-only -verify=cxx -x c++ %s +// good-no-diagnostics + +int i; // expected-note {{previous declaration is here}} \ + cxx-note {{previous definition is here}} +int i; // expected-warning {{duplicate declaration of 'i' is invalid in C++}} \ + cxx-error {{redefinition of 'i'}} + +int j = 12; // expected-note {{previous declaration is here}} \ + cxx-note {{previous definition is here}} +int j; // expected-warning {{duplicate declaration of 'j' is invalid in C++}} \ + cxx-error {{redefinition of 'j'}} + +int k; // expected-note {{previous declaration is here}} \ + cxx-note {{previous definition is here}} +int k = 12; // expected-warning {{duplicate declaration of 'k' is invalid in C++}} \ + cxx-error {{redefinition of 'k'}} + +// Cannot have two declarations with initializers, that is a redefinition in +// both C and C++. `````````` </details> https://github.com/llvm/llvm-project/pull/137967 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits