diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 71 | ||||
-rw-r--r-- | clang/test/CXX/drs/dr16xx.cpp | 2 | ||||
-rw-r--r-- | clang/test/Misc/warning-flags.c | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-initializer-constructor.cpp | 1 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-initializer-references.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-initializer-scalars.cpp | 10 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-return-init-list.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx98-compat.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/microsoft-new-delete.cpp | 2 |
10 files changed, 81 insertions, 22 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index f14d7097b78..d0949a2f4f8 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4171,9 +4171,10 @@ def warn_missing_field_initializers : Warning< "missing field %0 initializer">, InGroup<MissingFieldInitializers>, DefaultIgnore; def warn_braces_around_scalar_init : Warning< - "braces around scalar initializer">; + "braces around scalar initializer">, InGroup<DiagGroup<"braced-scalar-init">>; def ext_many_braces_around_scalar_init : ExtWarn< - "too many braces around scalar initializer">; + "too many braces around scalar initializer">, + InGroup<DiagGroup<"many-braces-around-scalar-init">>; def ext_complex_component_init : Extension< "complex initialization specifying real and imaginary components " "is an extension">, InGroup<DiagGroup<"complex-component-init">>; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index a25aada0c2b..dab06195878 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -754,6 +754,68 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity, } } +/// Warn that \p Entity was of scalar type and was initialized by a +/// single-element braced initializer list. +static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity, + SourceRange Braces) { + // Don't warn during template instantiation. If the initialization was + // non-dependent, we warned during the initial parse; otherwise, the + // type might not be scalar in some uses of the template. + if (!S.ActiveTemplateInstantiations.empty()) + return; + + unsigned DiagID = 0; + + switch (Entity.getKind()) { + case InitializedEntity::EK_VectorElement: + case InitializedEntity::EK_ComplexElement: + case InitializedEntity::EK_ArrayElement: + case InitializedEntity::EK_Parameter: + case InitializedEntity::EK_Parameter_CF_Audited: + case InitializedEntity::EK_Result: + // Extra braces here are suspicious. + DiagID = diag::warn_braces_around_scalar_init; + break; + + case InitializedEntity::EK_Member: + // Warn on aggregate initialization but not on ctor init list or + // default member initializer. + if (Entity.getParent()) + DiagID = diag::warn_braces_around_scalar_init; + break; + + case InitializedEntity::EK_Variable: + case InitializedEntity::EK_LambdaCapture: + // No warning, might be direct-list-initialization. + // FIXME: Should we warn for copy-list-initialization in these cases? + break; + + case InitializedEntity::EK_New: + case InitializedEntity::EK_Temporary: + case InitializedEntity::EK_CompoundLiteralInit: + // No warning, braces are part of the syntax of the underlying construct. + break; + + case InitializedEntity::EK_RelatedResult: + // No warning, we already warned when initializing the result. + break; + + case InitializedEntity::EK_Exception: + case InitializedEntity::EK_Base: + case InitializedEntity::EK_Delegating: + case InitializedEntity::EK_BlockElement: + llvm_unreachable("unexpected braced scalar init"); + } + + if (DiagID) { + S.Diag(Braces.getBegin(), DiagID) + << Braces + << FixItHint::CreateRemoval(Braces.getBegin()) + << FixItHint::CreateRemoval(Braces.getEnd()); + } +} + + /// Check whether the initializer \p IList (that was written with explicit /// braces) can be used to initialize an object of type \p T. /// @@ -829,12 +891,9 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, } } - if (!VerifyOnly && T->isScalarType() && IList->getNumInits() == 1 && - !TopLevelObject) - SemaRef.Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init) - << IList->getSourceRange() - << FixItHint::CreateRemoval(IList->getLocStart()) - << FixItHint::CreateRemoval(IList->getLocEnd()); + if (!VerifyOnly && T->isScalarType() && + IList->getNumInits() == 1 && !isa<InitListExpr>(IList->getInit(0))) + warnBracedScalarInit(SemaRef, Entity, IList->getSourceRange()); } void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity, diff --git a/clang/test/CXX/drs/dr16xx.cpp b/clang/test/CXX/drs/dr16xx.cpp index cbbd0e9be6f..ddb7d16869b 100644 --- a/clang/test/CXX/drs/dr16xx.cpp +++ b/clang/test/CXX/drs/dr16xx.cpp @@ -29,7 +29,7 @@ namespace dr1631 { // dr1631: 3.7 c++11 void f(int, A); void test() { - f({0}, {{1}}); + f({0}, {{1}}); // expected-warning {{braces around scalar init}} } namespace with_error { diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c index 74ab56667c9..657b44dc185 100644 --- a/clang/test/Misc/warning-flags.c +++ b/clang/test/Misc/warning-flags.c @@ -18,14 +18,13 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (96): +CHECK: Warnings without flags (94): CHECK-NEXT: ext_excess_initializers CHECK-NEXT: ext_excess_initializers_in_char_array_initializer CHECK-NEXT: ext_expected_semi_decl_list CHECK-NEXT: ext_explicit_specialization_storage_class CHECK-NEXT: ext_implicit_lib_function_decl CHECK-NEXT: ext_initializer_string_for_char_array_too_long -CHECK-NEXT: ext_many_braces_around_scalar_init CHECK-NEXT: ext_missing_declspec CHECK-NEXT: ext_missing_whitespace_after_macro_name CHECK-NEXT: ext_new_paren_array_nonconst @@ -50,7 +49,6 @@ CHECK-NEXT: warn_anon_bitfield_width_exceeds_type_size CHECK-NEXT: warn_arcmt_nsalloc_realloc CHECK-NEXT: warn_asm_label_on_auto_decl CHECK-NEXT: warn_bitfield_width_exceeds_type_size -CHECK-NEXT: warn_braces_around_scalar_init CHECK-NEXT: warn_c_kext CHECK-NEXT: warn_call_to_pure_virtual_member_function_from_ctor_dtor CHECK-NEXT: warn_call_wrong_number_of_arguments diff --git a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp index 0cd5aa7401a..6202bf620fe 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -142,6 +142,7 @@ namespace objects { one ov2(int); two ov2(F<3>); + // expected-warning@+1 {{braces around scalar initializer}} static_assert(sizeof(ov2({1})) == sizeof(one), "bad overload"); // list -> int ranks as identity static_assert(sizeof(ov2({1, 2, 3})) == sizeof(two), "bad overload"); // list -> F only viable } diff --git a/clang/test/SemaCXX/cxx0x-initializer-references.cpp b/clang/test/SemaCXX/cxx0x-initializer-references.cpp index dda68a3ec94..f9164fb1ae6 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-references.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-references.cpp @@ -110,7 +110,7 @@ namespace inner_init { struct D { C &&r; }; D d1 { 0 }; // ok, 0 implicitly converts to C D d2 { { 0 } }; // ok, { 0 } calls C(0) - D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 }) + D d3 { { { 0 } } }; // ok, { { 0 } } calls C({ 0 }), expected-warning {{braces around scalar init}} D d4 { { { { 0 } } } }; // expected-error {{no matching constructor for initialization of 'inner_init::C &&'}} struct E { explicit E(int); }; // expected-note 2{{here}} diff --git a/clang/test/SemaCXX/cxx0x-initializer-scalars.cpp b/clang/test/SemaCXX/cxx0x-initializer-scalars.cpp index 1475dcf911c..c9d5ffd1942 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-scalars.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-scalars.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -pedantic-errors struct one { char c[1]; }; struct two { char c[2]; }; @@ -55,7 +55,7 @@ namespace integral { int ar[10]; (void) ar[{1}]; // expected-error {{array subscript is not an integer}} - return {1}; + return {1}; // expected-warning {{braces around scalar init}} } void inline_init() { @@ -70,15 +70,15 @@ namespace integral { void function_call() { void takes_int(int); - takes_int({1}); + takes_int({1}); // expected-warning {{braces around scalar init}} } void overloaded_call() { one overloaded(int); two overloaded(double); - static_assert(sizeof(overloaded({0})) == sizeof(one), "bad overload"); - static_assert(sizeof(overloaded({0.0})) == sizeof(two), "bad overload"); + static_assert(sizeof(overloaded({0})) == sizeof(one), "bad overload"); // expected-warning {{braces around scalar init}} + static_assert(sizeof(overloaded({0.0})) == sizeof(two), "bad overload"); // expected-warning {{braces around scalar init}} void ambiguous(int, double); // expected-note {{candidate}} void ambiguous(double, int); // expected-note {{candidate}} diff --git a/clang/test/SemaCXX/cxx0x-return-init-list.cpp b/clang/test/SemaCXX/cxx0x-return-init-list.cpp index da83271c4d7..84bd89b210f 100644 --- a/clang/test/SemaCXX/cxx0x-return-init-list.cpp +++ b/clang/test/SemaCXX/cxx0x-return-init-list.cpp @@ -4,7 +4,7 @@ // required for libstdc++ 4.5) is supported in C++98. int test0(int i) { - return { i }; // expected-warning{{generalized initializer lists are a C++11 extension}} + return { i }; // expected-warning{{generalized initializer lists are a C++11 extension}} expected-warning {{scalar}} } template<typename T, typename U> diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp index 029e9098962..4227272d14e 100644 --- a/clang/test/SemaCXX/cxx98-compat.cpp +++ b/clang/test/SemaCXX/cxx98-compat.cpp @@ -74,10 +74,10 @@ int InitList(int i = {}) { // expected-warning {{generalized initializer lists a InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} struct { int a; const int &r; } rr = { 0, {0} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} - return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} + return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}} } struct DelayedDefaultArgumentParseInitList { - void f(int i = {1}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} + void f(int i = {1}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}} } }; diff --git a/clang/test/SemaCXX/microsoft-new-delete.cpp b/clang/test/SemaCXX/microsoft-new-delete.cpp index 6c9be228935..b929e618a03 100644 --- a/clang/test/SemaCXX/microsoft-new-delete.cpp +++ b/clang/test/SemaCXX/microsoft-new-delete.cpp @@ -31,4 +31,4 @@ struct explicit_ctor_tag {} ect; void *operator new[](size_t, explicit_ctor_tag, explicit_ctor); void *operator new(size_t, explicit_ctor_tag, int); void *t = new (ect, 0) int[4]; -void *u = new (ect, {0}) int[4]; +void *u = new (ect, {0}) int[4]; // expected-warning {{braces around scalar init}} |