https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/75332
>From d0a7276eb8014693656d3d931616d56ffe46730c Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com> Date: Wed, 13 Dec 2023 04:25:12 -0800 Subject: [PATCH 1/3] [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@-1 {{implicit conversion from 'double' to 'unsigned int' changes value from 0.5 to 0}} +} >From 3d6d16ac5291f3fd72cd6230077984346e4165cc Mon Sep 17 00:00:00 2001 From: Mariya Podchishchaeva <mariya.podchishcha...@intel.com> Date: Wed, 13 Dec 2023 20:51:47 +0100 Subject: [PATCH 2/3] Update clang/lib/Sema/SemaInit.cpp Co-authored-by: Erich Keane <eke...@nvidia.com> --- clang/lib/Sema/SemaInit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 7ff1b55d1fcba0..469346a2940477 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4488,7 +4488,7 @@ static void TryReferenceListInitialization(Sema &S, // Try to bind the reference here. TryReferenceInitializationCore(S, Entity, Kind, Initializer, cv1T1, T1, T1Quals, cv2T2, T2, T2Quals, Sequence, - true); + /*TopLevelOfInitList=*/true); if (Sequence) Sequence.RewrapReferenceInitList(cv1T1, InitList); return; >From 29eede77f5afbab726bf61f6cf93800d162a648a Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com> Date: Thu, 14 Dec 2023 06:09:20 -0800 Subject: [PATCH 3/3] Swap `getLocalUnqualifiedType` and `getNonReferenceType` --- clang/lib/Sema/SemaInit.cpp | 6 +++--- clang/test/SemaCXX/GH63151.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 469346a2940477..de0d92edb550dd 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -10437,7 +10437,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, : diag::warn_init_list_type_narrowing) << PostInit->getSourceRange() << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType().getNonReferenceType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; case NK_Constant_Narrowing: @@ -10448,7 +10448,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, : diag::warn_init_list_constant_narrowing) << PostInit->getSourceRange() << ConstantValue.getAsString(S.getASTContext(), ConstantType) - << EntityType.getLocalUnqualifiedType().getNonReferenceType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; case NK_Variable_Narrowing: @@ -10459,7 +10459,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, : diag::warn_init_list_variable_narrowing) << PostInit->getSourceRange() << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType().getNonReferenceType(); + << EntityType.getNonReferenceType().getLocalUnqualifiedType(); break; } diff --git a/clang/test/SemaCXX/GH63151.cpp b/clang/test/SemaCXX/GH63151.cpp index 3d5c3cc84a56db..2c7533ed88f3bb 100644 --- a/clang/test/SemaCXX/GH63151.cpp +++ b/clang/test/SemaCXX/GH63151.cpp @@ -4,9 +4,9 @@ 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 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 'const unsigned int' in initializer list}} - A d { 0.5 }; // expected-error {{type 'double' cannot be narrowed to 'const unsigned int' in initializer list}} + 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@-1 {{implicit conversion from 'double' to 'unsigned int' changes value from 0.5 to 0}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits