Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -8360,40 +8360,49 @@ // No narrowing occurred. return; - case NK_Type_Narrowing: + case NK_Type_Narrowing: { // 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(); - break; - - case NK_Constant_Narrowing: + bool DiagErr = + S.getLangOpts().CPlusPlus11 && + (!S.getLangOpts().MicrosoftExt || + S.getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)); + S.Diag(PostInit->getLocStart(), !DiagErr + ? diag::warn_init_list_type_narrowing + : diag::ext_init_list_type_narrowing) + << PostInit->getSourceRange() + << PreNarrowingType.getLocalUnqualifiedType() + << EntityType.getLocalUnqualifiedType(); + } break; + + case NK_Constant_Narrowing: { // A constant value was narrowed. + bool DiagErr = + S.getLangOpts().CPlusPlus11 && + (!S.getLangOpts().MicrosoftExt || + S.getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)); 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(); - break; - - case NK_Variable_Narrowing: + !DiagErr ? diag::warn_init_list_constant_narrowing + : diag::ext_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. + bool DiagErr = + S.getLangOpts().CPlusPlus11 && + (!S.getLangOpts().MicrosoftExt || + S.getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)); 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(); - break; + !DiagErr ? diag::warn_init_list_variable_narrowing + : diag::ext_init_list_variable_narrowing) + << PostInit->getSourceRange() + << PreNarrowingType.getLocalUnqualifiedType() + << EntityType.getLocalUnqualifiedType(); + } break; } SmallString<128> StaticCast; Index: clang/test/SemaCXX/ms-initlist-narrowing.cpp =================================================================== --- /dev/null +++ clang/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}} +}