Skip to content

Commit 132a529

Browse files
committed
[Sema] Add -Wc++11-narrowing-const-reference
llvm#75332 diagnosed narrowing involving const reference. Our depot has hundreds if not thousands of breakages (llvm#75332 (comment)). Add a subgroup of -Wc++11-narrowing to help users gradually fix their issues without regressing the existing -Wc++11-narrowing diagnostics.
1 parent b03f0c5 commit 132a529

File tree

5 files changed

+41
-11
lines changed

5 files changed

+41
-11
lines changed

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
348348
CXXPre20CompatPedantic,
349349
CXXPre23CompatPedantic]>;
350350

351-
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
351+
def CXX11NarrowingConstReference : DiagGroup<"c++11-narrowing-const-reference">;
352+
def CXX11Narrowing : DiagGroup<"c++11-narrowing", [CXX11NarrowingConstReference]>;
352353

353354
def CXX11WarnInconsistentOverrideDestructor :
354355
DiagGroup<"inconsistent-missing-destructor-override">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6158,12 +6158,24 @@ def err_illegal_initializer_type : Error<"illegal initializer type %0">;
61586158
def ext_init_list_type_narrowing : ExtWarn<
61596159
"type %0 cannot be narrowed to %1 in initializer list">,
61606160
InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
6161+
// *_narrowing_const_reference diagnostics have the same messages, but are
6162+
// controlled by -Wc++11-narrowing-const-reference for narrowing involving a
6163+
// const reference.
6164+
def ext_init_list_type_narrowing_const_reference : ExtWarn<
6165+
"type %0 cannot be narrowed to %1 in initializer list">,
6166+
InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
61616167
def ext_init_list_variable_narrowing : ExtWarn<
61626168
"non-constant-expression cannot be narrowed from type %0 to %1 in "
61636169
"initializer list">, InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
6170+
def ext_init_list_variable_narrowing_const_reference : ExtWarn<
6171+
"non-constant-expression cannot be narrowed from type %0 to %1 in "
6172+
"initializer list">, InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
61646173
def ext_init_list_constant_narrowing : ExtWarn<
61656174
"constant expression evaluates to %0 which cannot be narrowed to type %1">,
61666175
InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
6176+
def ext_init_list_constant_narrowing_const_reference : ExtWarn<
6177+
"constant expression evaluates to %0 which cannot be narrowed to type %1">,
6178+
InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
61676179
def warn_init_list_type_narrowing : Warning<
61686180
"type %0 cannot be narrowed to %1 in initializer list in C++11">,
61696181
InGroup<CXX11Narrowing>, DefaultIgnore;

clang/lib/Sema/SemaInit.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10410,40 +10410,53 @@ static void DiagnoseNarrowingInInitList(Sema &S,
1041010410
// No narrowing occurred.
1041110411
return;
1041210412

10413-
case NK_Type_Narrowing:
10413+
case NK_Type_Narrowing: {
1041410414
// This was a floating-to-integer conversion, which is always considered a
1041510415
// narrowing conversion even if the value is a constant and can be
1041610416
// represented exactly as an integer.
10417-
S.Diag(PostInit->getBeginLoc(), NarrowingErrs(S.getLangOpts())
10418-
? diag::ext_init_list_type_narrowing
10419-
: diag::warn_init_list_type_narrowing)
10417+
QualType T = EntityType.getNonReferenceType();
10418+
S.Diag(PostInit->getBeginLoc(),
10419+
NarrowingErrs(S.getLangOpts())
10420+
? (T == EntityType
10421+
? diag::ext_init_list_type_narrowing
10422+
: diag::ext_init_list_type_narrowing_const_reference)
10423+
: diag::warn_init_list_type_narrowing)
1042010424
<< PostInit->getSourceRange()
1042110425
<< PreNarrowingType.getLocalUnqualifiedType()
10422-
<< EntityType.getNonReferenceType().getLocalUnqualifiedType();
10426+
<< T.getLocalUnqualifiedType();
1042310427
break;
10428+
}
1042410429

10425-
case NK_Constant_Narrowing:
10430+
case NK_Constant_Narrowing: {
1042610431
// A constant value was narrowed.
10432+
QualType T = EntityType.getNonReferenceType();
1042710433
S.Diag(PostInit->getBeginLoc(),
1042810434
NarrowingErrs(S.getLangOpts())
10429-
? diag::ext_init_list_constant_narrowing
10435+
? (T == EntityType
10436+
? diag::ext_init_list_constant_narrowing
10437+
: diag::ext_init_list_constant_narrowing_const_reference)
1043010438
: diag::warn_init_list_constant_narrowing)
1043110439
<< PostInit->getSourceRange()
1043210440
<< ConstantValue.getAsString(S.getASTContext(), ConstantType)
1043310441
<< EntityType.getNonReferenceType().getLocalUnqualifiedType();
1043410442
break;
10443+
}
1043510444

10436-
case NK_Variable_Narrowing:
10445+
case NK_Variable_Narrowing: {
1043710446
// A variable's value may have been narrowed.
10447+
QualType T = EntityType.getNonReferenceType();
1043810448
S.Diag(PostInit->getBeginLoc(),
1043910449
NarrowingErrs(S.getLangOpts())
10440-
? diag::ext_init_list_variable_narrowing
10450+
? (T == EntityType
10451+
? diag::ext_init_list_variable_narrowing
10452+
: diag::ext_init_list_variable_narrowing_const_reference)
1044110453
: diag::warn_init_list_variable_narrowing)
1044210454
<< PostInit->getSourceRange()
1044310455
<< PreNarrowingType.getLocalUnqualifiedType()
1044410456
<< EntityType.getNonReferenceType().getLocalUnqualifiedType();
1044510457
break;
1044610458
}
10459+
}
1044710460

1044810461
SmallString<128> StaticCast;
1044910462
llvm::raw_svector_ostream OS(StaticCast);

clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-apple-macosx10.6.7 -verify %s
2+
// The following narrowing does not involve const references, so
3+
// -Wno-c++11-narrowing-const-reference does not suppress the errors.
4+
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -triple x86_64-apple-macosx10.6.7 -Wno-c++11-narrowing-const-reference -verify %s
25

36
// Verify that narrowing conversions in initializer lists cause errors in C++0x
47
// mode.

clang/test/SemaCXX/GH63151.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify %s
2-
2+
// RUN: %clang_cc1 -fsyntax-only -Wno-c++11-narrowing-const-reference -verify=allow %s
33

44
struct A { A(const unsigned &x) {} };
55

@@ -9,4 +9,5 @@ void foo(int p) {
99
A c { p }; // expected-error {{non-constant-expression cannot be narrowed from type 'int' to 'unsigned int' in initializer list}}
1010
A d { 0.5 }; // expected-error {{type 'double' cannot be narrowed to 'unsigned int' in initializer list}}
1111
// expected-warning@-1 {{implicit conversion from 'double' to 'unsigned int' changes value from 0.5 to 0}}
12+
// allow-warning@-2 {{implicit conversion from 'double' to 'unsigned int' changes value from 0.5 to 0}}
1213
}

0 commit comments

Comments
 (0)