Skip to content

Commit b685a55

Browse files
committed
[C] Add -Wtentative-definition-compat
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.
1 parent 6e43cdb commit b685a55

File tree

6 files changed

+42
-2
lines changed

6 files changed

+42
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ C Language Changes
171171
``-Wenum-conversion`` and ``-Wimplicit-int-enum-cast``. This conversion is an
172172
int-to-enum conversion because the enumeration on the right-hand side is
173173
promoted to ``int`` before the assignment.
174+
- Added ``-Wtentative-definition-compat``, grouped under ``-Wc++-compat``,
175+
which diagnoses tentative definitions in C with multiple declarations as
176+
being incompatible with C++. e.g.,
177+
178+
.. code-block:: c
179+
180+
// File scope
181+
int i;
182+
int i; // Vaild C, invalid C++, now diagnosed
174183
175184
C2y Feature Support
176185
^^^^^^^^^^^^^^^^^^^

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,10 @@ def DefaultConstInit : DiagGroup<"default-const-init", [DefaultConstInitUnsafe]>
162162
def ImplicitVoidPtrCast : DiagGroup<"implicit-void-ptr-cast">;
163163
def ImplicitIntToEnumCast : DiagGroup<"implicit-int-enum-cast",
164164
[ImplicitEnumEnumCast]>;
165+
def TentativeDefnCompat : DiagGroup<"tentative-definition-compat">;
165166
def CXXCompat: DiagGroup<"c++-compat", [ImplicitVoidPtrCast, DefaultConstInit,
166-
ImplicitIntToEnumCast, HiddenCppDecl]>;
167+
ImplicitIntToEnumCast, HiddenCppDecl,
168+
TentativeDefnCompat]>;
167169

168170
def ExternCCompat : DiagGroup<"extern-c-compat">;
169171
def KeywordCompat : DiagGroup<"keyword-compat">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7443,6 +7443,9 @@ def err_tentative_def_incomplete_type : Error<
74437443
def warn_tentative_incomplete_array : Warning<
74447444
"tentative array definition assumed to have one element">,
74457445
InGroup<DiagGroup<"tentative-definition-array">>;
7446+
def warn_cxx_compat_tentative_definition : Warning<
7447+
"duplicate declaration of %0 is invalid in C++">,
7448+
InGroup<TentativeDefnCompat>, DefaultIgnore;
74467449
def err_typecheck_incomplete_array_needs_initializer : Error<
74477450
"definition of variable with array type needs an explicit size "
74487451
"or an initializer">;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4750,6 +4750,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
47504750
if (Def && checkVarDeclRedefinition(Def, New))
47514751
return;
47524752
}
4753+
} else {
4754+
Diag(New->getLocation(), diag::warn_cxx_compat_tentative_definition) << New;
4755+
Diag(Old->getLocation(), diag::note_previous_declaration);
47534756
}
47544757

47554758
if (haveIncompatibleLanguageLinkages(Old, New)) {

clang/test/Sema/warn-default-const-init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wdefault-const-init %s
2-
// RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wc++-compat %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify=c,unsafe -Wc++-compat -Wno-tentative-definition-compat %s
33
// RUN: %clang_cc1 -fsyntax-only -verify=unsafe %s
44
// RUN: %clang_cc1 -fsyntax-only -verify=c -Wdefault-const-init -Wno-default-const-init-unsafe %s
55
// RUN: %clang_cc1 -fsyntax-only -verify=good -Wno-default-const-init-unsafe %s
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -Wtentative-definition-compat %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -Wc++-compat %s
3+
// RUN: %clang_cc1 -fsyntax-only -verify=good %s
4+
// RUN: %clang_cc1 -fsyntax-only -verify=cxx -x c++ %s
5+
// good-no-diagnostics
6+
7+
int i; // expected-note {{previous declaration is here}} \
8+
cxx-note {{previous definition is here}}
9+
int i; // expected-warning {{duplicate declaration of 'i' is invalid in C++}} \
10+
cxx-error {{redefinition of 'i'}}
11+
12+
int j = 12; // expected-note {{previous declaration is here}} \
13+
cxx-note {{previous definition is here}}
14+
int j; // expected-warning {{duplicate declaration of 'j' is invalid in C++}} \
15+
cxx-error {{redefinition of 'j'}}
16+
17+
int k; // expected-note {{previous declaration is here}} \
18+
cxx-note {{previous definition is here}}
19+
int k = 12; // expected-warning {{duplicate declaration of 'k' is invalid in C++}} \
20+
cxx-error {{redefinition of 'k'}}
21+
22+
// Cannot have two declarations with initializers, that is a redefinition in
23+
// both C and C++.

0 commit comments

Comments
 (0)