[clang] [clang] Report narrowing conversions with const references (PR #75332)
Mariya Podchishchaeva via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 13 04:45:22 PST 2023
https://github.com/Fznamznon created https://github.com/llvm/llvm-project/pull/75332
Fixes https://github.com/llvm/llvm-project/issues/63151
>From d0a7276eb8014693656d3d931616d56ffe46730c Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Wed, 13 Dec 2023 04:25:12 -0800
Subject: [PATCH] [clang] Report narrowing conversions with const references
Fixes https://github.com/llvm/llvm-project/issues/63151
---
clang/docs/ReleaseNotes.rst | 3 +++
clang/lib/Sema/SemaInit.cpp | 30 ++++++++++++++++++------------
clang/test/SemaCXX/GH63151.cpp | 12 ++++++++++++
3 files changed, 33 insertions(+), 12 deletions(-)
create mode 100644 clang/test/SemaCXX/GH63151.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 05d59d0da264f3..2aba1740a6b610 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..7ff1b55d1fcba0 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,
+ 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.getLocalUnqualifiedType().getNonReferenceType();
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.getLocalUnqualifiedType().getNonReferenceType();
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.getLocalUnqualifiedType().getNonReferenceType();
break;
}
diff --git a/clang/test/SemaCXX/GH63151.cpp b/clang/test/SemaCXX/GH63151.cpp
new file mode 100644
index 00000000000000..3d5c3cc84a56db
--- /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 'const unsigned int'}}
+ A b { 0 };
+ A c { p }; // expected-error {{non-constant-expression cannot be narrowed from type 'int' to 'const unsigned int' in initializer list}}
+ A d { 0.5 }; // expected-error {{type 'double' cannot be narrowed to 'const 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