From c3261ea295e010b1720e19b4ddd05b966366fea1 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 19 Jun 2018 23:19:34 +0000 Subject: [PATCH] clang-cl: Emit narrowing diag for initializer lists if -fmsc-version is at least 1900 (i.e. MSVC2015). Diagnostics for narrowing conversions in initializer lists are currently DefaultIgnored in Microsoft mode. But MSVC 2015 did add warnings about narrowing conversions (C2397), so clang-cl can remove its special case code if MSCompatibilityVersion is new enough. (In MSVC, C2397 is just a warning and in clang it's default-mapped to an error, but it can be remapped, and disabled with -Wno-c++11-narrowing, so that should be fine.) Fixes PR37314. https://reviews.llvm.org/D48296 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335082 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaInit.cpp | 42 ++++++++++++++------------ test/SemaCXX/ms-initlist-narrowing.cpp | 17 +++++++++++ 2 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 test/SemaCXX/ms-initlist-narrowing.cpp diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index dc9e29858d..cd6683e44f 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -8331,6 +8331,11 @@ void InitializationSequence::dump() const { dump(llvm::errs()); } +static bool NarrowingErrs(const LangOptions &L) { + return L.CPlusPlus11 && + (!L.MicrosoftExt || L.isCompatibleWithMSVC(LangOptions::MSVC2015)); +} + static void DiagnoseNarrowingInInitList(Sema &S, const ImplicitConversionSequence &ICS, QualType PreNarrowingType, @@ -8364,35 +8369,34 @@ static void DiagnoseNarrowingInInitList(Sema &S, // This was a floating-to-integer conversion, which is always considered a // narrowing conversion even if the value is a constant and can be // represented exactly as an integer. - S.Diag(PostInit->getLocStart(), - (S.getLangOpts().MicrosoftExt || !S.getLangOpts().CPlusPlus11) - ? diag::warn_init_list_type_narrowing - : diag::ext_init_list_type_narrowing) - << PostInit->getSourceRange() - << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType(); + S.Diag(PostInit->getLocStart(), NarrowingErrs(S.getLangOpts()) + ? diag::ext_init_list_type_narrowing + : diag::warn_init_list_type_narrowing) + << PostInit->getSourceRange() + << PreNarrowingType.getLocalUnqualifiedType() + << EntityType.getLocalUnqualifiedType(); break; case NK_Constant_Narrowing: // A constant value was narrowed. S.Diag(PostInit->getLocStart(), - (S.getLangOpts().MicrosoftExt || !S.getLangOpts().CPlusPlus11) - ? diag::warn_init_list_constant_narrowing - : diag::ext_init_list_constant_narrowing) - << PostInit->getSourceRange() - << ConstantValue.getAsString(S.getASTContext(), ConstantType) - << EntityType.getLocalUnqualifiedType(); + NarrowingErrs(S.getLangOpts()) + ? diag::ext_init_list_constant_narrowing + : diag::warn_init_list_constant_narrowing) + << PostInit->getSourceRange() + << ConstantValue.getAsString(S.getASTContext(), ConstantType) + << EntityType.getLocalUnqualifiedType(); break; case NK_Variable_Narrowing: // A variable's value may have been narrowed. S.Diag(PostInit->getLocStart(), - (S.getLangOpts().MicrosoftExt || !S.getLangOpts().CPlusPlus11) - ? diag::warn_init_list_variable_narrowing - : diag::ext_init_list_variable_narrowing) - << PostInit->getSourceRange() - << PreNarrowingType.getLocalUnqualifiedType() - << EntityType.getLocalUnqualifiedType(); + NarrowingErrs(S.getLangOpts()) + ? diag::ext_init_list_variable_narrowing + : diag::warn_init_list_variable_narrowing) + << PostInit->getSourceRange() + << PreNarrowingType.getLocalUnqualifiedType() + << EntityType.getLocalUnqualifiedType(); break; } diff --git a/test/SemaCXX/ms-initlist-narrowing.cpp b/test/SemaCXX/ms-initlist-narrowing.cpp new file mode 100644 index 0000000000..687a206d49 --- /dev/null +++ b/test/SemaCXX/ms-initlist-narrowing.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -fms-compatibility-version=19.0 -std=c++11 + +int ai[] = { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} + +template +struct Agg { + T t; +}; + +void f(int i) { + // Constant expression. + Agg f8 = {1E50}; // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{silence}} + + // Non-constant expression. + double d = 1.0; + Agg f2 = {d}; // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{silence}} +} -- 2.50.1