Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
- Added ``-Wunterminated-string-initialization``, grouped under ``-Wextra``,
which diagnoses an initialization from a string literal where only the null
terminator cannot be stored. e.g.,
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,11 @@ 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,
InitStringTooLongForCpp]>;
InitStringTooLongForCpp,
TentativeDefnCompat]>;

def ExternCCompat : DiagGroup<"extern-c-compat">;
def KeywordCompat : DiagGroup<"keyword-compat">;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -7455,6 +7455,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">;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Sema/warn-default-const-init.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down
23 changes: 23 additions & 0 deletions clang/test/Sema/warn-tentative-defn-compat.c
Original file line number Diff line number Diff line change
@@ -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++.