[clang] cd09f21 - [clang] Report narrowing conversions with const references (#75332)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 15 00:42:24 PST 2023
Author: Mariya Podchishchaeva
Date: 2023-12-15T09:42:20+01:00
New Revision: cd09f21b223688d58c00866c6e01f3a073993a4c
URL: https://github.com/llvm/llvm-project/commit/cd09f21b223688d58c00866c6e01f3a073993a4c
DIFF: https://github.com/llvm/llvm-project/commit/cd09f21b223688d58c00866c6e01f3a073993a4c.diff
LOG: [clang] Report narrowing conversions with const references (#75332)
Fixes https://github.com/llvm/llvm-project/issues/63151
---------
Co-authored-by: Erich Keane <ekeane at nvidia.com>
Added:
clang/test/SemaCXX/GH63151.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaInit.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f5ae6bb8925202..26ba4f8f72508a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -521,6 +521,9 @@ Improvements to Clang's diagnostics
| ~~~~~~~^~~~~
- Clang now diagnoses definitions of friend function specializations, e.g. ``friend void f<>(int) {}``.
+- Clang now diagnoses narrowing conversions involving const references.
+ (`#63151: <https://github.com/llvm/llvm-project/issues/63151>`_).
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 4028b2d642b212..de0d92edb550dd 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4432,7 +4432,8 @@ static void TryReferenceInitializationCore(Sema &S,
Qualifiers T1Quals,
QualType cv2T2, QualType T2,
Qualifiers T2Quals,
- InitializationSequence &Sequence);
+ InitializationSequence &Sequence,
+ bool TopLevelOfInitList);
static void TryValueInitialization(Sema &S,
const InitializedEntity &Entity,
@@ -4486,7 +4487,8 @@ static void TryReferenceListInitialization(Sema &S,
if (RefRelationship >= Sema::Ref_Related) {
// Try to bind the reference here.
TryReferenceInitializationCore(S, Entity, Kind, Initializer, cv1T1, T1,
- T1Quals, cv2T2, T2, T2Quals, Sequence);
+ T1Quals, cv2T2, T2, T2Quals, Sequence,
+ /*TopLevelOfInitList=*/true);
if (Sequence)
Sequence.RewrapReferenceInitList(cv1T1, InitList);
return;
@@ -4945,11 +4947,11 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
Expr *CurInitExpr);
/// Attempt reference initialization (C++0x [dcl.init.ref])
-static void TryReferenceInitialization(Sema &S,
- const InitializedEntity &Entity,
+static void TryReferenceInitialization(Sema &S, const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr *Initializer,
- InitializationSequence &Sequence) {
+ InitializationSequence &Sequence,
+ bool TopLevelOfInitList) {
QualType DestType = Entity.getType();
QualType cv1T1 = DestType->castAs<ReferenceType>()->getPointeeType();
Qualifiers T1Quals;
@@ -4967,7 +4969,8 @@ static void TryReferenceInitialization(Sema &S,
// Delegate everything else to a subfunction.
TryReferenceInitializationCore(S, Entity, Kind, Initializer, cv1T1, T1,
- T1Quals, cv2T2, T2, T2Quals, Sequence);
+ T1Quals, cv2T2, T2, T2Quals, Sequence,
+ TopLevelOfInitList);
}
/// Determine whether an expression is a non-referenceable glvalue (one to
@@ -4990,7 +4993,8 @@ static void TryReferenceInitializationCore(Sema &S,
Qualifiers T1Quals,
QualType cv2T2, QualType T2,
Qualifiers T2Quals,
- InitializationSequence &Sequence) {
+ InitializationSequence &Sequence,
+ bool TopLevelOfInitList) {
QualType DestType = Entity.getType();
SourceLocation DeclLoc = Initializer->getBeginLoc();
@@ -5264,7 +5268,8 @@ static void TryReferenceInitializationCore(Sema &S,
Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed);
return;
} else {
- Sequence.AddConversionSequenceStep(ICS, TempEntity.getType());
+ Sequence.AddConversionSequenceStep(ICS, TempEntity.getType(),
+ TopLevelOfInitList);
}
// [...] If T1 is reference-related to T2, cv1 must be the
@@ -6228,7 +6233,8 @@ void InitializationSequence::InitializeFrom(Sema &S,
else if (isa<InitListExpr>(Args[0]))
SetFailed(FK_ParenthesizedListInitForReference);
else
- TryReferenceInitialization(S, Entity, Kind, Args[0], *this);
+ TryReferenceInitialization(S, Entity, Kind, Args[0], *this,
+ TopLevelOfInitList);
return;
}
@@ -10431,7 +10437,7 @@ static void DiagnoseNarrowingInInitList(Sema &S,
: diag::warn_init_list_type_narrowing)
<< PostInit->getSourceRange()
<< PreNarrowingType.getLocalUnqualifiedType()
- << EntityType.getLocalUnqualifiedType();
+ << EntityType.getNonReferenceType().getLocalUnqualifiedType();
break;
case NK_Constant_Narrowing:
@@ -10442,7 +10448,7 @@ static void DiagnoseNarrowingInInitList(Sema &S,
: diag::warn_init_list_constant_narrowing)
<< PostInit->getSourceRange()
<< ConstantValue.getAsString(S.getASTContext(), ConstantType)
- << EntityType.getLocalUnqualifiedType();
+ << EntityType.getNonReferenceType().getLocalUnqualifiedType();
break;
case NK_Variable_Narrowing:
@@ -10453,7 +10459,7 @@ static void DiagnoseNarrowingInInitList(Sema &S,
: diag::warn_init_list_variable_narrowing)
<< PostInit->getSourceRange()
<< PreNarrowingType.getLocalUnqualifiedType()
- << EntityType.getLocalUnqualifiedType();
+ << EntityType.getNonReferenceType().getLocalUnqualifiedType();
break;
}
diff --git a/clang/test/SemaCXX/GH63151.cpp b/clang/test/SemaCXX/GH63151.cpp
new file mode 100644
index 00000000000000..2c7533ed88f3bb
--- /dev/null
+++ b/clang/test/SemaCXX/GH63151.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+struct A { A(const unsigned &x) {} };
+
+void foo(int p) {
+ A a { -1 }; // expected-error {{constant expression evaluates to -1 which cannot be narrowed to type 'unsigned int'}}
+ A b { 0 };
+ A c { p }; // expected-error {{non-constant-expression cannot be narrowed from type 'int' to 'unsigned int' in initializer list}}
+ A d { 0.5 }; // expected-error {{type 'double' cannot be narrowed to 'unsigned int' in initializer list}}
+ // expected-warning at -1 {{implicit conversion from 'double' to 'unsigned int' changes value from 0.5 to 0}}
+}
More information about the cfe-commits
mailing list