From: Chandler Carruth Date: Tue, 4 Jan 2011 04:44:35 +0000 (+0000) Subject: Enhance the diagnostic for negative array sizes to include the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b2b5cc0cf908d516a107d373db963f692449a8a8;p=clang Enhance the diagnostic for negative array sizes to include the declaration name of the array when present. This ensures that a poor-man's C++03 static_assert will include the user error message often embedded in the name. Update all the tests to reflect the new wording, and add a test for the name behavior. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122802 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index ffef24269a..bf28070f18 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2167,6 +2167,8 @@ def err_illegal_message_expr_incomplete_type : Error< "objective-c message has incomplete result type %0">; def err_illegal_decl_array_of_references : Error< "'%0' declared as array of references of type %1">; +def err_decl_negative_array_size : Error< + "'%0' declared as an array with a negative size">; def err_array_star_outside_prototype : Error< "star modifier used outside of function prototype">; def err_illegal_decl_pointer_to_reference : Error< diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index c70d5befbb..453531d98d 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -711,9 +711,12 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, // C99 6.7.5.2p1: If the expression is a constant expression, it shall // have a value greater than zero. if (ConstVal.isSigned() && ConstVal.isNegative()) { - Diag(ArraySize->getLocStart(), - diag::err_typecheck_negative_array_size) - << ArraySize->getSourceRange(); + if (Entity) + Diag(ArraySize->getLocStart(), diag::err_decl_negative_array_size) + << getPrintableNameForEntity(Entity) << ArraySize->getSourceRange(); + else + Diag(ArraySize->getLocStart(), diag::err_typecheck_negative_array_size) + << ArraySize->getSourceRange(); return QualType(); } if (ConstVal == 0) { diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp index f032bf9979..bb4a48eb5b 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp @@ -16,7 +16,7 @@ struct Abstract { virtual void fn() = 0; }; // expected-note {{pure virtual}} Abstract ar5[10]; // expected-error {{abstract class}} // If we have a size, it must be greater than zero. -int ar6[-1]; // expected-error {{array size is negative}} +int ar6[-1]; // expected-error {{array with a negative size}} int ar7[0u]; // expected-warning {{zero size arrays are an extension}} // An array with unknown bound is incomplete. @@ -42,3 +42,13 @@ template struct S { typename T::type x; // expected-error {{has no members}} }; S ar10[10]; // expected-note {{requested here}} + +// Ensure that negative array size errors include the name of the declared +// array as this is often used to simulate static_assert with template +// instantiations, placing the 'error message' in the declarator name. +int +user_error_message +[-1]; // expected-error {{user_error_message}} +typedef int +another_user_error_message +[-1]; // expected-error {{another_user_error_message}} diff --git a/test/Sema/array-constraint.c b/test/Sema/array-constraint.c index fe7fdc7115..bee33c09ef 100644 --- a/test/Sema/array-constraint.c +++ b/test/Sema/array-constraint.c @@ -36,7 +36,7 @@ pfunc xx(int f[](void)) { // expected-error {{'f' declared as array of functions void check_size() { float f; int size_not_int[f]; // expected-error {{size of array has non-integer type 'float'}} - int negative_size[1-2]; // expected-error{{array size is negative}} + int negative_size[1-2]; // expected-error{{array with a negative size}} int zero_size[0]; // expected-warning{{zero size arrays are an extension}} } diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp index ba2b80dacd..4ea77a3e54 100644 --- a/test/SemaCXX/virtual-override.cpp +++ b/test/SemaCXX/virtual-override.cpp @@ -121,7 +121,7 @@ namespace T9 { struct a { }; template struct b : a { - int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}} + int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} }; class A { diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp index f4c1887c25..e208bd2b89 100644 --- a/test/SemaTemplate/attributes.cpp +++ b/test/SemaTemplate/attributes.cpp @@ -7,7 +7,7 @@ namespace attribute_aligned { }; template struct check { - int check_failed[X ? 1 : -1]; // expected-error {{array size is negative}} + int check_failed[X ? 1 : -1]; // expected-error {{array with a negative size}} }; template struct check_alignment { diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp index 8d54926b96..5d301be2fb 100644 --- a/test/SemaTemplate/default-expr-arguments.cpp +++ b/test/SemaTemplate/default-expr-arguments.cpp @@ -151,7 +151,7 @@ namespace pr5301 { namespace PR5810 { template struct allocator { - allocator() { int a[sizeof(T) ? -1 : -1]; } // expected-error2 {{array size is negative}} + allocator() { int a[sizeof(T) ? -1 : -1]; } // expected-error2 {{array with a negative size}} }; template diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp index 419ae93daa..703daea3e6 100644 --- a/test/SemaTemplate/friend-template.cpp +++ b/test/SemaTemplate/friend-template.cpp @@ -93,7 +93,7 @@ namespace test4 { }; template void f(const A&) { - int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}} + int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} } void f() { diff --git a/test/SemaTemplate/instantiate-default-assignment-operator.cpp b/test/SemaTemplate/instantiate-default-assignment-operator.cpp index 8b97f59e87..31cdef59d9 100644 --- a/test/SemaTemplate/instantiate-default-assignment-operator.cpp +++ b/test/SemaTemplate/instantiate-default-assignment-operator.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s template struct PassRefPtr { }; template struct RefPtr { - RefPtr& operator=(const RefPtr&) { int a[sizeof(T) ? -1 : -1];} // expected-error 2 {{array size is negative}} + RefPtr& operator=(const RefPtr&) { int a[sizeof(T) ? -1 : -1];} // expected-error 2 {{array with a negative size}} RefPtr& operator=(const PassRefPtr&); }; diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp index 11efe5b7f3..d923f2b555 100644 --- a/test/SemaTemplate/instantiate-expr-4.cpp +++ b/test/SemaTemplate/instantiate-expr-4.cpp @@ -46,8 +46,8 @@ template struct Temporaries0<5, 7>; // Ensure that both the constructor and the destructor are instantiated by // checking for parse errors from each. template struct BadX { - BadX() { int a[-N]; } // expected-error {{array size is negative}} - ~BadX() { int a[-N]; } // expected-error {{array size is negative}} + BadX() { int a[-N]; } // expected-error {{array with a negative size}} + ~BadX() { int a[-N]; } // expected-error {{array with a negative size}} }; template diff --git a/test/SemaTemplate/instantiate-member-expr.cpp b/test/SemaTemplate/instantiate-member-expr.cpp index 6c0e91bac8..a31569a0c3 100644 --- a/test/SemaTemplate/instantiate-member-expr.cpp +++ b/test/SemaTemplate/instantiate-member-expr.cpp @@ -6,7 +6,7 @@ struct S { template struct vector { - void push_back(const T&) { int a[sizeof(T) ? -1: -1]; } // expected-error {{array size is negative}} + void push_back(const T&) { int a[sizeof(T) ? -1: -1]; } // expected-error {{array with a negative size}} }; class ExprEngine { diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp index dca0f62170..0db90e3cbf 100644 --- a/test/SemaTemplate/instantiate-member-pointers.cpp +++ b/test/SemaTemplate/instantiate-member-pointers.cpp @@ -61,7 +61,7 @@ namespace ValueDepMemberPointer { typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}} }; template void S::instantiate() { - int a[(int)sizeof(T)-42]; // expected-error{{array size is negative}} + int a[(int)sizeof(T)-42]; // expected-error{{array with a negative size}} } S s; }